forked from OSchip/llvm-project
[flang] Use a common enum class in evaluate and runtime for type category.
Original-commit: flang-compiler/f18@5012e652af Reviewed-on: https://github.com/flang-compiler/f18/pull/162 Tree-same-pre-rewrite: false
This commit is contained in:
parent
2dce7b9554
commit
51b3ceaafe
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef FORTRAN_COMMON_FORTRAN_H_
|
||||
#define FORTRAN_COMMON_FORTRAN_H_
|
||||
|
||||
// Fortran language concepts that are used in many phases are defined
|
||||
// once here to avoid redundancy and needless translation.
|
||||
|
||||
#include "idioms.h"
|
||||
|
||||
namespace Fortran::common {
|
||||
|
||||
// Fortran has five kinds of intrinsic data, and the derived types.
|
||||
ENUM_CLASS(TypeCategory, Integer, Real, Complex, Character, Logical, Derived)
|
||||
|
||||
} // namespace Fortran::common
|
||||
#endif // FORTRAN_COMMON_FORTRAN_H_
|
|
@ -25,20 +25,21 @@ namespace Fortran::evaluate {
|
|||
|
||||
// An expression of some specific result type.
|
||||
template<typename A> class Expr;
|
||||
template<int KIND> using IntegerExpr = Expr<Type<Category::Integer, KIND>>;
|
||||
template<int KIND> using IntegerExpr = Expr<Type<TypeCategory::Integer, KIND>>;
|
||||
using DefaultIntegerExpr = IntegerExpr<DefaultInteger::kind>;
|
||||
template<int KIND> using RealExpr = Expr<Type<Category::Real, KIND>>;
|
||||
template<int KIND> using ComplexExpr = Expr<Type<Category::Complex, KIND>>;
|
||||
template<int KIND> using CharacterExpr = Expr<Type<Category::Character, KIND>>;
|
||||
template<int KIND> using LogicalExpr = Expr<Type<Category::Logical, KIND>>;
|
||||
template<int KIND> using RealExpr = Expr<Type<TypeCategory::Real, KIND>>;
|
||||
template<int KIND> using ComplexExpr = Expr<Type<TypeCategory::Complex, KIND>>;
|
||||
template<int KIND>
|
||||
using CharacterExpr = Expr<Type<TypeCategory::Character, KIND>>;
|
||||
template<int KIND> using LogicalExpr = Expr<Type<TypeCategory::Logical, KIND>>;
|
||||
|
||||
// An expression whose result is within one particular type category and
|
||||
// of any supported kind.
|
||||
using AnyKindIntegerExpr = Expr<AnyKindType<Category::Integer>>;
|
||||
using AnyKindRealExpr = Expr<AnyKindType<Category::Real>>;
|
||||
using AnyKindComplexExpr = Expr<AnyKindType<Category::Complex>>;
|
||||
using AnyKindCharacterExpr = Expr<AnyKindType<Category::Character>>;
|
||||
using AnyKindLogicalExpr = Expr<AnyKindType<Category::Logical>>;
|
||||
using AnyKindIntegerExpr = Expr<AnyKindType<TypeCategory::Integer>>;
|
||||
using AnyKindRealExpr = Expr<AnyKindType<TypeCategory::Real>>;
|
||||
using AnyKindComplexExpr = Expr<AnyKindType<TypeCategory::Complex>>;
|
||||
using AnyKindCharacterExpr = Expr<AnyKindType<TypeCategory::Character>>;
|
||||
using AnyKindLogicalExpr = Expr<AnyKindType<TypeCategory::Logical>>;
|
||||
|
||||
// A completely generic expression.
|
||||
struct GenericExpr;
|
||||
|
|
|
@ -44,12 +44,12 @@ std::ostream &DumpExpr(std::ostream &o, const std::variant<A...> &u) {
|
|||
return o;
|
||||
}
|
||||
|
||||
template<Category CAT>
|
||||
template<TypeCategory CAT>
|
||||
std::ostream &Expr<AnyKindType<CAT>>::Dump(std::ostream &o) const {
|
||||
return DumpExpr(o, u);
|
||||
}
|
||||
|
||||
template<Category CAT>
|
||||
template<TypeCategory CAT>
|
||||
std::ostream &CategoryComparison<CAT>::Dump(std::ostream &o) const {
|
||||
return DumpExpr(o, u);
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ auto Binary<CRTP, RESULT, A, B>::Fold(FoldingContext &context)
|
|||
|
||||
template<int KIND>
|
||||
auto IntegerExpr<KIND>::ConvertInteger::FoldScalar(FoldingContext &context,
|
||||
const ScalarConstant<Category::Integer> &c) -> std::optional<Scalar> {
|
||||
const ScalarConstant<TypeCategory::Integer> &c) -> std::optional<Scalar> {
|
||||
return std::visit(
|
||||
[&](auto &x) -> std::optional<Scalar> {
|
||||
auto converted{Scalar::ConvertSigned(x)};
|
||||
|
@ -246,7 +246,7 @@ auto IntegerExpr<KIND>::ConvertInteger::FoldScalar(FoldingContext &context,
|
|||
|
||||
template<int KIND>
|
||||
auto IntegerExpr<KIND>::ConvertReal::FoldScalar(FoldingContext &context,
|
||||
const ScalarConstant<Category::Real> &c) -> std::optional<Scalar> {
|
||||
const ScalarConstant<TypeCategory::Real> &c) -> std::optional<Scalar> {
|
||||
return std::visit(
|
||||
[&](auto &x) -> std::optional<Scalar> {
|
||||
auto converted{x.template ToInteger<Scalar>()};
|
||||
|
@ -402,7 +402,7 @@ static void RealFlagWarnings(
|
|||
|
||||
template<int KIND>
|
||||
auto RealExpr<KIND>::ConvertInteger::FoldScalar(FoldingContext &context,
|
||||
const ScalarConstant<Category::Integer> &c) -> std::optional<Scalar> {
|
||||
const ScalarConstant<TypeCategory::Integer> &c) -> std::optional<Scalar> {
|
||||
return std::visit(
|
||||
[&](auto &x) -> std::optional<Scalar> {
|
||||
auto converted{Scalar::FromInteger(x)};
|
||||
|
@ -414,7 +414,7 @@ auto RealExpr<KIND>::ConvertInteger::FoldScalar(FoldingContext &context,
|
|||
|
||||
template<int KIND>
|
||||
auto RealExpr<KIND>::ConvertReal::FoldScalar(FoldingContext &context,
|
||||
const ScalarConstant<Category::Real> &c) -> std::optional<Scalar> {
|
||||
const ScalarConstant<TypeCategory::Real> &c) -> std::optional<Scalar> {
|
||||
return std::visit(
|
||||
[&](auto &x) -> std::optional<Scalar> {
|
||||
auto converted{Scalar::Convert(x)};
|
||||
|
@ -470,7 +470,7 @@ auto RealExpr<KIND>::Power::FoldScalar(FoldingContext &context, const Scalar &a,
|
|||
|
||||
template<int KIND>
|
||||
auto RealExpr<KIND>::IntPower::FoldScalar(FoldingContext &context,
|
||||
const Scalar &a, const ScalarConstant<Category::Integer> &b)
|
||||
const Scalar &a, const ScalarConstant<TypeCategory::Integer> &b)
|
||||
-> std::optional<Scalar> {
|
||||
return std::visit(
|
||||
[&](const auto &pow) -> std::optional<Scalar> {
|
||||
|
@ -580,7 +580,7 @@ auto ComplexExpr<KIND>::Power::FoldScalar(FoldingContext &context,
|
|||
|
||||
template<int KIND>
|
||||
auto ComplexExpr<KIND>::IntPower::FoldScalar(FoldingContext &context,
|
||||
const Scalar &a, const ScalarConstant<Category::Integer> &b)
|
||||
const Scalar &a, const ScalarConstant<TypeCategory::Integer> &b)
|
||||
-> std::optional<Scalar> {
|
||||
return std::visit(
|
||||
[&](const auto &pow) -> std::optional<Scalar> {
|
||||
|
@ -672,7 +672,7 @@ template<typename A>
|
|||
auto Comparison<A>::FoldScalar(FoldingContext &c,
|
||||
const OperandScalarConstant &a, const OperandScalarConstant &b)
|
||||
-> std::optional<Scalar> {
|
||||
if constexpr (A::category == Category::Integer) {
|
||||
if constexpr (A::category == TypeCategory::Integer) {
|
||||
switch (a.CompareSigned(b)) {
|
||||
case Ordering::Less:
|
||||
return {opr == RelationalOperator::LE || opr == RelationalOperator::LE ||
|
||||
|
@ -685,7 +685,7 @@ auto Comparison<A>::FoldScalar(FoldingContext &c,
|
|||
opr == RelationalOperator::GT};
|
||||
}
|
||||
}
|
||||
if constexpr (A::category == Category::Real) {
|
||||
if constexpr (A::category == TypeCategory::Real) {
|
||||
switch (a.Compare(b)) {
|
||||
case Relation::Less:
|
||||
return {opr == RelationalOperator::LE || opr == RelationalOperator::LE ||
|
||||
|
@ -699,12 +699,12 @@ auto Comparison<A>::FoldScalar(FoldingContext &c,
|
|||
case Relation::Unordered: return std::nullopt;
|
||||
}
|
||||
}
|
||||
if constexpr (A::category == Category::Complex) {
|
||||
if constexpr (A::category == TypeCategory::Complex) {
|
||||
bool eqOk{opr == RelationalOperator::LE || opr == RelationalOperator::EQ ||
|
||||
opr == RelationalOperator::GE};
|
||||
return {eqOk == a.Equals(b)};
|
||||
}
|
||||
if constexpr (A::category == Category::Character) {
|
||||
if constexpr (A::category == TypeCategory::Character) {
|
||||
switch (Compare(a, b)) {
|
||||
case Ordering::Less:
|
||||
return {opr == RelationalOperator::LE || opr == RelationalOperator::LE ||
|
||||
|
@ -781,7 +781,7 @@ std::optional<GenericScalar> GenericExpr::ScalarValue() const {
|
|||
u);
|
||||
}
|
||||
|
||||
template<Category CAT>
|
||||
template<TypeCategory CAT>
|
||||
auto Expr<AnyKindType<CAT>>::ScalarValue() const -> std::optional<Scalar> {
|
||||
return std::visit(
|
||||
[](const auto &x) -> std::optional<Scalar> {
|
||||
|
@ -793,7 +793,7 @@ auto Expr<AnyKindType<CAT>>::ScalarValue() const -> std::optional<Scalar> {
|
|||
u);
|
||||
}
|
||||
|
||||
template<Category CAT>
|
||||
template<TypeCategory CAT>
|
||||
auto Expr<AnyKindType<CAT>>::Fold(FoldingContext &context)
|
||||
-> std::optional<Scalar> {
|
||||
return std::visit(
|
||||
|
@ -817,47 +817,47 @@ std::optional<GenericScalar> GenericExpr::Fold(FoldingContext &context) {
|
|||
u);
|
||||
}
|
||||
|
||||
template class Expr<AnyKindType<Category::Integer>>;
|
||||
template class Expr<AnyKindType<Category::Real>>;
|
||||
template class Expr<AnyKindType<Category::Complex>>;
|
||||
template class Expr<AnyKindType<Category::Character>>;
|
||||
template class Expr<AnyKindType<Category::Logical>>;
|
||||
template class Expr<AnyKindType<TypeCategory::Integer>>;
|
||||
template class Expr<AnyKindType<TypeCategory::Real>>;
|
||||
template class Expr<AnyKindType<TypeCategory::Complex>>;
|
||||
template class Expr<AnyKindType<TypeCategory::Character>>;
|
||||
template class Expr<AnyKindType<TypeCategory::Logical>>;
|
||||
|
||||
template class Expr<Type<Category::Integer, 1>>;
|
||||
template class Expr<Type<Category::Integer, 2>>;
|
||||
template class Expr<Type<Category::Integer, 4>>;
|
||||
template class Expr<Type<Category::Integer, 8>>;
|
||||
template class Expr<Type<Category::Integer, 16>>;
|
||||
template class Expr<Type<Category::Real, 2>>;
|
||||
template class Expr<Type<Category::Real, 4>>;
|
||||
template class Expr<Type<Category::Real, 8>>;
|
||||
template class Expr<Type<Category::Real, 10>>;
|
||||
template class Expr<Type<Category::Real, 16>>;
|
||||
template class Expr<Type<Category::Complex, 2>>;
|
||||
template class Expr<Type<Category::Complex, 4>>;
|
||||
template class Expr<Type<Category::Complex, 8>>;
|
||||
template class Expr<Type<Category::Complex, 10>>;
|
||||
template class Expr<Type<Category::Complex, 16>>;
|
||||
template class Expr<Type<Category::Character, 1>>;
|
||||
template class Expr<Type<Category::Logical, 1>>;
|
||||
template class Expr<Type<Category::Logical, 2>>;
|
||||
template class Expr<Type<Category::Logical, 4>>;
|
||||
template class Expr<Type<Category::Logical, 8>>;
|
||||
template class Expr<Type<TypeCategory::Integer, 1>>;
|
||||
template class Expr<Type<TypeCategory::Integer, 2>>;
|
||||
template class Expr<Type<TypeCategory::Integer, 4>>;
|
||||
template class Expr<Type<TypeCategory::Integer, 8>>;
|
||||
template class Expr<Type<TypeCategory::Integer, 16>>;
|
||||
template class Expr<Type<TypeCategory::Real, 2>>;
|
||||
template class Expr<Type<TypeCategory::Real, 4>>;
|
||||
template class Expr<Type<TypeCategory::Real, 8>>;
|
||||
template class Expr<Type<TypeCategory::Real, 10>>;
|
||||
template class Expr<Type<TypeCategory::Real, 16>>;
|
||||
template class Expr<Type<TypeCategory::Complex, 2>>;
|
||||
template class Expr<Type<TypeCategory::Complex, 4>>;
|
||||
template class Expr<Type<TypeCategory::Complex, 8>>;
|
||||
template class Expr<Type<TypeCategory::Complex, 10>>;
|
||||
template class Expr<Type<TypeCategory::Complex, 16>>;
|
||||
template class Expr<Type<TypeCategory::Character, 1>>;
|
||||
template class Expr<Type<TypeCategory::Logical, 1>>;
|
||||
template class Expr<Type<TypeCategory::Logical, 2>>;
|
||||
template class Expr<Type<TypeCategory::Logical, 4>>;
|
||||
template class Expr<Type<TypeCategory::Logical, 8>>;
|
||||
|
||||
template struct Comparison<Type<Category::Integer, 1>>;
|
||||
template struct Comparison<Type<Category::Integer, 2>>;
|
||||
template struct Comparison<Type<Category::Integer, 4>>;
|
||||
template struct Comparison<Type<Category::Integer, 8>>;
|
||||
template struct Comparison<Type<Category::Integer, 16>>;
|
||||
template struct Comparison<Type<Category::Real, 2>>;
|
||||
template struct Comparison<Type<Category::Real, 4>>;
|
||||
template struct Comparison<Type<Category::Real, 8>>;
|
||||
template struct Comparison<Type<Category::Real, 10>>;
|
||||
template struct Comparison<Type<Category::Real, 16>>;
|
||||
template struct Comparison<Type<Category::Complex, 2>>;
|
||||
template struct Comparison<Type<Category::Complex, 4>>;
|
||||
template struct Comparison<Type<Category::Complex, 8>>;
|
||||
template struct Comparison<Type<Category::Complex, 10>>;
|
||||
template struct Comparison<Type<Category::Complex, 16>>;
|
||||
template struct Comparison<Type<Category::Character, 1>>;
|
||||
template struct Comparison<Type<TypeCategory::Integer, 1>>;
|
||||
template struct Comparison<Type<TypeCategory::Integer, 2>>;
|
||||
template struct Comparison<Type<TypeCategory::Integer, 4>>;
|
||||
template struct Comparison<Type<TypeCategory::Integer, 8>>;
|
||||
template struct Comparison<Type<TypeCategory::Integer, 16>>;
|
||||
template struct Comparison<Type<TypeCategory::Real, 2>>;
|
||||
template struct Comparison<Type<TypeCategory::Real, 4>>;
|
||||
template struct Comparison<Type<TypeCategory::Real, 8>>;
|
||||
template struct Comparison<Type<TypeCategory::Real, 10>>;
|
||||
template struct Comparison<Type<TypeCategory::Real, 16>>;
|
||||
template struct Comparison<Type<TypeCategory::Complex, 2>>;
|
||||
template struct Comparison<Type<TypeCategory::Complex, 4>>;
|
||||
template struct Comparison<Type<TypeCategory::Complex, 8>>;
|
||||
template struct Comparison<Type<TypeCategory::Complex, 10>>;
|
||||
template struct Comparison<Type<TypeCategory::Complex, 16>>;
|
||||
template struct Comparison<Type<TypeCategory::Character, 1>>;
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -100,24 +100,25 @@ private:
|
|||
|
||||
// Per-category expressions
|
||||
|
||||
template<int KIND> class Expr<Type<Category::Integer, KIND>> {
|
||||
template<int KIND> class Expr<Type<TypeCategory::Integer, KIND>> {
|
||||
public:
|
||||
using Result = Type<Category::Integer, KIND>;
|
||||
using Result = Type<TypeCategory::Integer, KIND>;
|
||||
using Scalar = typename Result::Value;
|
||||
using FoldableTrait = std::true_type;
|
||||
|
||||
struct ConvertInteger
|
||||
: public Unary<ConvertInteger, Result, AnyKindType<Category::Integer>> {
|
||||
using Unary<ConvertInteger, Result, AnyKindType<Category::Integer>>::Unary;
|
||||
: public Unary<ConvertInteger, Result, AnyKindType<TypeCategory::Integer>> {
|
||||
using Unary<ConvertInteger, Result,
|
||||
AnyKindType<TypeCategory::Integer>>::Unary;
|
||||
static std::optional<Scalar> FoldScalar(
|
||||
FoldingContext &, const ScalarConstant<Category::Integer> &);
|
||||
FoldingContext &, const ScalarConstant<TypeCategory::Integer> &);
|
||||
};
|
||||
|
||||
struct ConvertReal
|
||||
: public Unary<ConvertReal, Result, AnyKindType<Category::Real>> {
|
||||
using Unary<ConvertReal, Result, AnyKindType<Category::Real>>::Unary;
|
||||
: public Unary<ConvertReal, Result, AnyKindType<TypeCategory::Real>> {
|
||||
using Unary<ConvertReal, Result, AnyKindType<TypeCategory::Real>>::Unary;
|
||||
static std::optional<Scalar> FoldScalar(
|
||||
FoldingContext &, const ScalarConstant<Category::Real> &);
|
||||
FoldingContext &, const ScalarConstant<TypeCategory::Real> &);
|
||||
};
|
||||
|
||||
template<typename CRTP> using Un = Unary<CRTP, Result>;
|
||||
|
@ -203,9 +204,9 @@ private:
|
|||
u_;
|
||||
};
|
||||
|
||||
template<int KIND> class Expr<Type<Category::Real, KIND>> {
|
||||
template<int KIND> class Expr<Type<TypeCategory::Real, KIND>> {
|
||||
public:
|
||||
using Result = Type<Category::Real, KIND>;
|
||||
using Result = Type<TypeCategory::Real, KIND>;
|
||||
using Scalar = typename Result::Value;
|
||||
using FoldableTrait = std::true_type;
|
||||
|
||||
|
@ -213,16 +214,17 @@ public:
|
|||
// and part access operations (resp.). Conversions between kinds of
|
||||
// Complex are done via decomposition to Real and reconstruction.
|
||||
struct ConvertInteger
|
||||
: public Unary<ConvertInteger, Result, AnyKindType<Category::Integer>> {
|
||||
using Unary<ConvertInteger, Result, AnyKindType<Category::Integer>>::Unary;
|
||||
: public Unary<ConvertInteger, Result, AnyKindType<TypeCategory::Integer>> {
|
||||
using Unary<ConvertInteger, Result,
|
||||
AnyKindType<TypeCategory::Integer>>::Unary;
|
||||
static std::optional<Scalar> FoldScalar(
|
||||
FoldingContext &, const ScalarConstant<Category::Integer> &);
|
||||
FoldingContext &, const ScalarConstant<TypeCategory::Integer> &);
|
||||
};
|
||||
struct ConvertReal
|
||||
: public Unary<ConvertReal, Result, AnyKindType<Category::Real>> {
|
||||
using Unary<ConvertReal, Result, AnyKindType<Category::Real>>::Unary;
|
||||
: public Unary<ConvertReal, Result, AnyKindType<TypeCategory::Real>> {
|
||||
using Unary<ConvertReal, Result, AnyKindType<TypeCategory::Real>>::Unary;
|
||||
static std::optional<Scalar> FoldScalar(
|
||||
FoldingContext &, const ScalarConstant<Category::Real> &);
|
||||
FoldingContext &, const ScalarConstant<TypeCategory::Real> &);
|
||||
};
|
||||
template<typename CRTP> using Un = Unary<CRTP, Result>;
|
||||
template<typename CRTP> using Bin = Binary<CRTP, Result>;
|
||||
|
@ -261,12 +263,12 @@ public:
|
|||
static std::optional<Scalar> FoldScalar(
|
||||
FoldingContext &, const Scalar &, const Scalar &);
|
||||
};
|
||||
struct IntPower
|
||||
: public Binary<IntPower, Result, Result, AnyKindType<Category::Integer>> {
|
||||
struct IntPower : public Binary<IntPower, Result, Result,
|
||||
AnyKindType<TypeCategory::Integer>> {
|
||||
using Binary<IntPower, Result, Result,
|
||||
AnyKindType<Category::Integer>>::Binary;
|
||||
AnyKindType<TypeCategory::Integer>>::Binary;
|
||||
static std::optional<Scalar> FoldScalar(FoldingContext &, const Scalar &,
|
||||
const ScalarConstant<Category::Integer> &);
|
||||
const ScalarConstant<TypeCategory::Integer> &);
|
||||
};
|
||||
struct Max : public Bin<Max> {
|
||||
using Bin<Max>::Bin;
|
||||
|
@ -278,7 +280,7 @@ public:
|
|||
static std::optional<Scalar> FoldScalar(
|
||||
FoldingContext &, const Scalar &, const Scalar &);
|
||||
};
|
||||
using Cplx = Type<Category::Complex, KIND>;
|
||||
using Cplx = Type<TypeCategory::Complex, KIND>;
|
||||
using CplxScalar = typename Cplx::Value;
|
||||
template<typename CRTP> using CplxUn = Unary<CRTP, Result, Cplx>;
|
||||
struct RealPart : public CplxUn<RealPart> {
|
||||
|
@ -321,9 +323,9 @@ private:
|
|||
u_;
|
||||
};
|
||||
|
||||
template<int KIND> class Expr<Type<Category::Complex, KIND>> {
|
||||
template<int KIND> class Expr<Type<TypeCategory::Complex, KIND>> {
|
||||
public:
|
||||
using Result = Type<Category::Complex, KIND>;
|
||||
using Result = Type<TypeCategory::Complex, KIND>;
|
||||
using Scalar = typename Result::Value;
|
||||
using FoldableTrait = std::true_type;
|
||||
template<typename CRTP> using Un = Unary<CRTP, Result>;
|
||||
|
@ -363,14 +365,14 @@ public:
|
|||
static std::optional<Scalar> FoldScalar(
|
||||
FoldingContext &, const Scalar &, const Scalar &);
|
||||
};
|
||||
struct IntPower
|
||||
: public Binary<IntPower, Result, Result, AnyKindType<Category::Integer>> {
|
||||
struct IntPower : public Binary<IntPower, Result, Result,
|
||||
AnyKindType<TypeCategory::Integer>> {
|
||||
using Binary<IntPower, Result, Result,
|
||||
AnyKindType<Category::Integer>>::Binary;
|
||||
AnyKindType<TypeCategory::Integer>>::Binary;
|
||||
static std::optional<Scalar> FoldScalar(FoldingContext &, const Scalar &,
|
||||
const ScalarConstant<Category::Integer> &);
|
||||
const ScalarConstant<TypeCategory::Integer> &);
|
||||
};
|
||||
using Part = Type<Category::Real, KIND>;
|
||||
using Part = Type<TypeCategory::Real, KIND>;
|
||||
using PartScalar = typename Part::Value;
|
||||
struct CMPLX : public Binary<CMPLX, Result, Part> {
|
||||
using Binary<CMPLX, Result, Part>::Binary;
|
||||
|
@ -397,9 +399,9 @@ private:
|
|||
u_;
|
||||
};
|
||||
|
||||
template<int KIND> class Expr<Type<Category::Character, KIND>> {
|
||||
template<int KIND> class Expr<Type<TypeCategory::Character, KIND>> {
|
||||
public:
|
||||
using Result = Type<Category::Character, KIND>;
|
||||
using Result = Type<TypeCategory::Character, KIND>;
|
||||
using Scalar = typename Result::Value;
|
||||
using FoldableTrait = std::true_type;
|
||||
template<typename CRTP> using Bin = Binary<CRTP, Result>;
|
||||
|
@ -447,8 +449,8 @@ ENUM_CLASS(RelationalOperator, LT, LE, EQ, NE, GE, GT)
|
|||
|
||||
template<typename A>
|
||||
struct Comparison
|
||||
: public Binary<Comparison<A>, Type<Category::Logical, 1>, A> {
|
||||
using Base = Binary<Comparison, Type<Category::Logical, 1>, A>;
|
||||
: public Binary<Comparison<A>, Type<TypeCategory::Logical, 1>, A> {
|
||||
using Base = Binary<Comparison, Type<TypeCategory::Logical, 1>, A>;
|
||||
using typename Base::Scalar;
|
||||
using OperandScalarConstant = typename Base::LeftScalar;
|
||||
CLASS_BOILERPLATE(Comparison)
|
||||
|
@ -461,27 +463,27 @@ struct Comparison
|
|||
RelationalOperator opr;
|
||||
};
|
||||
|
||||
extern template struct Comparison<Type<Category::Integer, 1>>;
|
||||
extern template struct Comparison<Type<Category::Integer, 2>>;
|
||||
extern template struct Comparison<Type<Category::Integer, 4>>;
|
||||
extern template struct Comparison<Type<Category::Integer, 8>>;
|
||||
extern template struct Comparison<Type<Category::Integer, 16>>;
|
||||
extern template struct Comparison<Type<Category::Real, 2>>;
|
||||
extern template struct Comparison<Type<Category::Real, 4>>;
|
||||
extern template struct Comparison<Type<Category::Real, 8>>;
|
||||
extern template struct Comparison<Type<Category::Real, 10>>;
|
||||
extern template struct Comparison<Type<Category::Real, 16>>;
|
||||
extern template struct Comparison<Type<Category::Complex, 2>>;
|
||||
extern template struct Comparison<Type<Category::Complex, 4>>;
|
||||
extern template struct Comparison<Type<Category::Complex, 8>>;
|
||||
extern template struct Comparison<Type<Category::Complex, 10>>;
|
||||
extern template struct Comparison<Type<Category::Complex, 16>>;
|
||||
extern template struct Comparison<Type<Category::Character, 1>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Integer, 1>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Integer, 2>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Integer, 4>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Integer, 8>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Integer, 16>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Real, 2>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Real, 4>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Real, 8>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Real, 10>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Real, 16>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Complex, 2>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Complex, 4>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Complex, 8>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Complex, 10>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Complex, 16>>;
|
||||
extern template struct Comparison<Type<TypeCategory::Character, 1>>;
|
||||
|
||||
// Dynamically polymorphic comparisons whose operands are expressions of
|
||||
// the same supported kind of a particular type category.
|
||||
template<Category CAT> struct CategoryComparison {
|
||||
using Scalar = typename Type<Category::Logical, 1>::Value;
|
||||
template<TypeCategory CAT> struct CategoryComparison {
|
||||
using Scalar = typename Type<TypeCategory::Logical, 1>::Value;
|
||||
CLASS_BOILERPLATE(CategoryComparison)
|
||||
template<int KIND> using KindComparison = Comparison<Type<CAT, KIND>>;
|
||||
template<int KIND> CategoryComparison(const KindComparison<KIND> &x) : u{x} {}
|
||||
|
@ -491,9 +493,9 @@ template<Category CAT> struct CategoryComparison {
|
|||
typename KindsVariant<CAT, KindComparison>::type u;
|
||||
};
|
||||
|
||||
template<int KIND> class Expr<Type<Category::Logical, KIND>> {
|
||||
template<int KIND> class Expr<Type<TypeCategory::Logical, KIND>> {
|
||||
public:
|
||||
using Result = Type<Category::Logical, KIND>;
|
||||
using Result = Type<TypeCategory::Logical, KIND>;
|
||||
using Scalar = typename Result::Value;
|
||||
using FoldableTrait = std::true_type;
|
||||
struct Not : Unary<Not, Result> {
|
||||
|
@ -525,9 +527,9 @@ public:
|
|||
CLASS_BOILERPLATE(Expr)
|
||||
Expr(const Scalar &x) : u_{x} {}
|
||||
Expr(bool x) : u_{Scalar{x}} {}
|
||||
template<Category CAT, int K>
|
||||
template<TypeCategory CAT, int K>
|
||||
Expr(const Comparison<Type<CAT, K>> &x) : u_{CategoryComparison<CAT>{x}} {}
|
||||
template<Category CAT, int K>
|
||||
template<TypeCategory CAT, int K>
|
||||
Expr(Comparison<Type<CAT, K>> &&x)
|
||||
: u_{CategoryComparison<CAT>{std::move(x)}} {}
|
||||
template<typename A> Expr(const A &x) : u_(x) {}
|
||||
|
@ -543,36 +545,37 @@ public:
|
|||
private:
|
||||
std::variant<Scalar, CopyableIndirection<DataRef>,
|
||||
CopyableIndirection<FunctionRef>, Not, And, Or, Eqv, Neqv,
|
||||
CategoryComparison<Category::Integer>, CategoryComparison<Category::Real>,
|
||||
CategoryComparison<Category::Complex>,
|
||||
CategoryComparison<Category::Character>>
|
||||
CategoryComparison<TypeCategory::Integer>,
|
||||
CategoryComparison<TypeCategory::Real>,
|
||||
CategoryComparison<TypeCategory::Complex>,
|
||||
CategoryComparison<TypeCategory::Character>>
|
||||
u_;
|
||||
};
|
||||
|
||||
extern template class Expr<Type<Category::Integer, 1>>;
|
||||
extern template class Expr<Type<Category::Integer, 2>>;
|
||||
extern template class Expr<Type<Category::Integer, 4>>;
|
||||
extern template class Expr<Type<Category::Integer, 8>>;
|
||||
extern template class Expr<Type<Category::Integer, 16>>;
|
||||
extern template class Expr<Type<Category::Real, 2>>;
|
||||
extern template class Expr<Type<Category::Real, 4>>;
|
||||
extern template class Expr<Type<Category::Real, 8>>;
|
||||
extern template class Expr<Type<Category::Real, 10>>;
|
||||
extern template class Expr<Type<Category::Real, 16>>;
|
||||
extern template class Expr<Type<Category::Complex, 2>>;
|
||||
extern template class Expr<Type<Category::Complex, 4>>;
|
||||
extern template class Expr<Type<Category::Complex, 8>>;
|
||||
extern template class Expr<Type<Category::Complex, 10>>;
|
||||
extern template class Expr<Type<Category::Complex, 16>>;
|
||||
extern template class Expr<Type<Category::Character, 1>>;
|
||||
extern template class Expr<Type<Category::Logical, 1>>;
|
||||
extern template class Expr<Type<Category::Logical, 2>>;
|
||||
extern template class Expr<Type<Category::Logical, 4>>;
|
||||
extern template class Expr<Type<Category::Logical, 8>>;
|
||||
extern template class Expr<Type<TypeCategory::Integer, 1>>;
|
||||
extern template class Expr<Type<TypeCategory::Integer, 2>>;
|
||||
extern template class Expr<Type<TypeCategory::Integer, 4>>;
|
||||
extern template class Expr<Type<TypeCategory::Integer, 8>>;
|
||||
extern template class Expr<Type<TypeCategory::Integer, 16>>;
|
||||
extern template class Expr<Type<TypeCategory::Real, 2>>;
|
||||
extern template class Expr<Type<TypeCategory::Real, 4>>;
|
||||
extern template class Expr<Type<TypeCategory::Real, 8>>;
|
||||
extern template class Expr<Type<TypeCategory::Real, 10>>;
|
||||
extern template class Expr<Type<TypeCategory::Real, 16>>;
|
||||
extern template class Expr<Type<TypeCategory::Complex, 2>>;
|
||||
extern template class Expr<Type<TypeCategory::Complex, 4>>;
|
||||
extern template class Expr<Type<TypeCategory::Complex, 8>>;
|
||||
extern template class Expr<Type<TypeCategory::Complex, 10>>;
|
||||
extern template class Expr<Type<TypeCategory::Complex, 16>>;
|
||||
extern template class Expr<Type<TypeCategory::Character, 1>>;
|
||||
extern template class Expr<Type<TypeCategory::Logical, 1>>;
|
||||
extern template class Expr<Type<TypeCategory::Logical, 2>>;
|
||||
extern template class Expr<Type<TypeCategory::Logical, 4>>;
|
||||
extern template class Expr<Type<TypeCategory::Logical, 8>>;
|
||||
|
||||
// Dynamically polymorphic expressions that can hold any supported kind
|
||||
// of a specific intrinsic type category.
|
||||
template<Category CAT> class Expr<AnyKindType<CAT>> {
|
||||
template<TypeCategory CAT> class Expr<AnyKindType<CAT>> {
|
||||
public:
|
||||
using Result = AnyKindType<CAT>;
|
||||
using Scalar = typename Result::Value;
|
||||
|
@ -586,11 +589,11 @@ public:
|
|||
typename KindsVariant<CAT, KindExpr>::type u;
|
||||
};
|
||||
|
||||
extern template class Expr<AnyKindType<Category::Integer>>;
|
||||
extern template class Expr<AnyKindType<Category::Real>>;
|
||||
extern template class Expr<AnyKindType<Category::Complex>>;
|
||||
extern template class Expr<AnyKindType<Category::Character>>;
|
||||
extern template class Expr<AnyKindType<Category::Logical>>;
|
||||
extern template class Expr<AnyKindType<TypeCategory::Integer>>;
|
||||
extern template class Expr<AnyKindType<TypeCategory::Real>>;
|
||||
extern template class Expr<AnyKindType<TypeCategory::Complex>>;
|
||||
extern template class Expr<AnyKindType<TypeCategory::Character>>;
|
||||
extern template class Expr<AnyKindType<TypeCategory::Logical>>;
|
||||
|
||||
// A completely generic expression, polymorphic across the intrinsic type
|
||||
// categories and each of their kinds.
|
||||
|
@ -598,9 +601,9 @@ struct GenericExpr {
|
|||
using Scalar = GenericScalar;
|
||||
using FoldableTrait = std::true_type;
|
||||
CLASS_BOILERPLATE(GenericExpr)
|
||||
template<Category CAT, int KIND>
|
||||
template<TypeCategory CAT, int KIND>
|
||||
GenericExpr(const Expr<Type<CAT, KIND>> &x) : u{Expr<AnyKindType<CAT>>{x}} {}
|
||||
template<Category CAT, int KIND>
|
||||
template<TypeCategory CAT, int KIND>
|
||||
GenericExpr(Expr<Type<CAT, KIND>> &&x)
|
||||
: u{Expr<AnyKindType<CAT>>{std::move(x)}} {}
|
||||
template<typename A> GenericExpr(const A &x) : u{x} {}
|
||||
|
|
|
@ -24,16 +24,17 @@
|
|||
#include "integer.h"
|
||||
#include "logical.h"
|
||||
#include "real.h"
|
||||
#include "../common/fortran.h"
|
||||
#include "../common/idioms.h"
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
namespace Fortran::evaluate {
|
||||
|
||||
ENUM_CLASS(Category, Integer, Real, Complex, Character, Logical, Derived)
|
||||
using common::TypeCategory;
|
||||
|
||||
template<Category C, int KIND> struct TypeBase {
|
||||
static constexpr Category category{C};
|
||||
template<TypeCategory C, int KIND> struct TypeBase {
|
||||
static constexpr TypeCategory category{C};
|
||||
static constexpr int kind{KIND};
|
||||
static constexpr bool hasLen{false};
|
||||
static std::string Dump() {
|
||||
|
@ -41,51 +42,55 @@ template<Category C, int KIND> struct TypeBase {
|
|||
}
|
||||
};
|
||||
|
||||
template<Category C, int KIND> struct Type;
|
||||
template<TypeCategory C, int KIND> struct Type;
|
||||
|
||||
template<int KIND>
|
||||
struct Type<Category::Integer, KIND>
|
||||
: public TypeBase<Category::Integer, KIND> {
|
||||
struct Type<TypeCategory::Integer, KIND>
|
||||
: public TypeBase<TypeCategory::Integer, KIND> {
|
||||
using Value = value::Integer<8 * KIND>;
|
||||
};
|
||||
|
||||
template<> struct Type<Category::Real, 2> : public TypeBase<Category::Real, 2> {
|
||||
using Value = value::Real<typename Type<Category::Integer, 2>::Value, 11>;
|
||||
using Complex = Type<Category::Complex, 2>;
|
||||
};
|
||||
|
||||
template<> struct Type<Category::Real, 4> : public TypeBase<Category::Real, 4> {
|
||||
using Value = value::Real<typename Type<Category::Integer, 4>::Value, 24>;
|
||||
using Complex = Type<Category::Complex, 2>;
|
||||
};
|
||||
|
||||
template<> struct Type<Category::Real, 8> : public TypeBase<Category::Real, 8> {
|
||||
using Value = value::Real<typename Type<Category::Integer, 8>::Value, 53>;
|
||||
using Complex = Type<Category::Complex, 2>;
|
||||
template<>
|
||||
struct Type<TypeCategory::Real, 2> : public TypeBase<TypeCategory::Real, 2> {
|
||||
using Value = value::Real<typename Type<TypeCategory::Integer, 2>::Value, 11>;
|
||||
using Complex = Type<TypeCategory::Complex, 2>;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Type<Category::Real, 10> : public TypeBase<Category::Real, 10> {
|
||||
struct Type<TypeCategory::Real, 4> : public TypeBase<TypeCategory::Real, 4> {
|
||||
using Value = value::Real<typename Type<TypeCategory::Integer, 4>::Value, 24>;
|
||||
using Complex = Type<TypeCategory::Complex, 2>;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Type<TypeCategory::Real, 8> : public TypeBase<TypeCategory::Real, 8> {
|
||||
using Value = value::Real<typename Type<TypeCategory::Integer, 8>::Value, 53>;
|
||||
using Complex = Type<TypeCategory::Complex, 2>;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Type<TypeCategory::Real, 10> : public TypeBase<TypeCategory::Real, 10> {
|
||||
using Value = value::Real<value::Integer<80>, 64, false>;
|
||||
using Complex = Type<Category::Complex, 2>;
|
||||
using Complex = Type<TypeCategory::Complex, 2>;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Type<Category::Real, 16> : public TypeBase<Category::Real, 16> {
|
||||
using Value = value::Real<typename Type<Category::Integer, 16>::Value, 112>;
|
||||
using Complex = Type<Category::Complex, 2>;
|
||||
struct Type<TypeCategory::Real, 16> : public TypeBase<TypeCategory::Real, 16> {
|
||||
using Value =
|
||||
value::Real<typename Type<TypeCategory::Integer, 16>::Value, 112>;
|
||||
using Complex = Type<TypeCategory::Complex, 2>;
|
||||
};
|
||||
|
||||
// The KIND type parameter on COMPLEX is the kind of each of its components.
|
||||
template<int KIND>
|
||||
struct Type<Category::Complex, KIND>
|
||||
: public TypeBase<Category::Complex, KIND> {
|
||||
using Part = Type<Category::Real, KIND>;
|
||||
struct Type<TypeCategory::Complex, KIND>
|
||||
: public TypeBase<TypeCategory::Complex, KIND> {
|
||||
using Part = Type<TypeCategory::Real, KIND>;
|
||||
using Value = value::Complex<typename Part::Value>;
|
||||
};
|
||||
|
||||
template<int KIND> struct Type<Category::Character, KIND> {
|
||||
static constexpr Category category{Category::Character};
|
||||
template<int KIND> struct Type<TypeCategory::Character, KIND> {
|
||||
static constexpr TypeCategory category{TypeCategory::Character};
|
||||
static constexpr int kind{KIND};
|
||||
static constexpr bool hasLen{true};
|
||||
using Value = std::string;
|
||||
|
@ -95,8 +100,8 @@ template<int KIND> struct Type<Category::Character, KIND> {
|
|||
};
|
||||
|
||||
template<int KIND>
|
||||
struct Type<Category::Logical, KIND>
|
||||
: public TypeBase<Category::Logical, KIND> {
|
||||
struct Type<TypeCategory::Logical, KIND>
|
||||
: public TypeBase<TypeCategory::Logical, KIND> {
|
||||
using Value = value::Logical<8 * KIND>;
|
||||
};
|
||||
|
||||
|
@ -107,15 +112,15 @@ struct Type<Category::Logical, KIND>
|
|||
// two numeric storage units.
|
||||
// TODO: Support a compile-time option to default everything to KIND=8
|
||||
|
||||
using DefaultReal = Type<Category::Real, 4>;
|
||||
using DefaultDoublePrecision = Type<Category::Real, 2 * DefaultReal::kind>;
|
||||
using DefaultInteger = Type<Category::Integer, DefaultReal::kind>;
|
||||
using DefaultReal = Type<TypeCategory::Real, 4>;
|
||||
using DefaultDoublePrecision = Type<TypeCategory::Real, 2 * DefaultReal::kind>;
|
||||
using DefaultInteger = Type<TypeCategory::Integer, DefaultReal::kind>;
|
||||
using IntrinsicTypeParameterType = DefaultInteger;
|
||||
using DefaultComplex = typename DefaultReal::Complex;
|
||||
using DefaultLogical = Type<Category::Logical, DefaultInteger::kind>;
|
||||
using DefaultCharacter = Type<Category::Character, 1>;
|
||||
using DefaultLogical = Type<TypeCategory::Logical, DefaultInteger::kind>;
|
||||
using DefaultCharacter = Type<TypeCategory::Character, 1>;
|
||||
|
||||
using SubscriptInteger = Type<Category::Integer, 8>;
|
||||
using SubscriptInteger = Type<TypeCategory::Integer, 8>;
|
||||
|
||||
// These macros invoke other macros on each of the supported kinds of
|
||||
// a given category.
|
||||
|
@ -131,27 +136,28 @@ using SubscriptInteger = Type<Category::Integer, 8>;
|
|||
// applications of some class template to all of the supported kinds of
|
||||
// a category of intrinsic type.
|
||||
#define TKIND(K) T<K>
|
||||
template<Category CAT, template<int> class T> struct KindsVariant;
|
||||
template<template<int> class T> struct KindsVariant<Category::Integer, T> {
|
||||
template<TypeCategory CAT, template<int> class T> struct KindsVariant;
|
||||
template<template<int> class T> struct KindsVariant<TypeCategory::Integer, T> {
|
||||
using type = std::variant<FOR_EACH_INTEGER_KIND(TKIND, COMMA)>;
|
||||
};
|
||||
template<template<int> class T> struct KindsVariant<Category::Real, T> {
|
||||
template<template<int> class T> struct KindsVariant<TypeCategory::Real, T> {
|
||||
using type = std::variant<FOR_EACH_REAL_KIND(TKIND, COMMA)>;
|
||||
};
|
||||
template<template<int> class T> struct KindsVariant<Category::Complex, T> {
|
||||
template<template<int> class T> struct KindsVariant<TypeCategory::Complex, T> {
|
||||
using type = std::variant<FOR_EACH_COMPLEX_KIND(TKIND, COMMA)>;
|
||||
};
|
||||
template<template<int> class T> struct KindsVariant<Category::Character, T> {
|
||||
template<template<int> class T>
|
||||
struct KindsVariant<TypeCategory::Character, T> {
|
||||
using type = std::variant<FOR_EACH_CHARACTER_KIND(TKIND, COMMA)>;
|
||||
};
|
||||
template<template<int> class T> struct KindsVariant<Category::Logical, T> {
|
||||
template<template<int> class T> struct KindsVariant<TypeCategory::Logical, T> {
|
||||
using type = std::variant<FOR_EACH_LOGICAL_KIND(TKIND, COMMA)>;
|
||||
};
|
||||
#undef TKIND
|
||||
|
||||
// Holds a scalar constant of any kind within a particular intrinsic type
|
||||
// category.
|
||||
template<Category CAT> struct ScalarConstant {
|
||||
template<TypeCategory CAT> struct ScalarConstant {
|
||||
CLASS_BOILERPLATE(ScalarConstant)
|
||||
template<int KIND> using KindScalar = typename Type<CAT, KIND>::Value;
|
||||
template<typename A> ScalarConstant(const A &x) : u{x} {}
|
||||
|
@ -164,25 +170,26 @@ template<Category CAT> struct ScalarConstant {
|
|||
// Holds a scalar constant of any intrinsic category and size.
|
||||
struct GenericScalar {
|
||||
CLASS_BOILERPLATE(GenericScalar)
|
||||
template<Category CAT, int KIND>
|
||||
template<TypeCategory CAT, int KIND>
|
||||
GenericScalar(const typename Type<CAT, KIND>::Value &x)
|
||||
: u{ScalarConstant<CAT>{x}} {}
|
||||
template<Category CAT, int KIND>
|
||||
template<TypeCategory CAT, int KIND>
|
||||
GenericScalar(typename Type<CAT, KIND>::Value &&x)
|
||||
: u{ScalarConstant<CAT>{std::move(x)}} {}
|
||||
template<typename A> GenericScalar(const A &x) : u{x} {}
|
||||
template<typename A>
|
||||
GenericScalar(std::enable_if_t<!std::is_reference_v<A>, A> &&x)
|
||||
: u{std::move(x)} {}
|
||||
std::variant<ScalarConstant<Category::Integer>,
|
||||
ScalarConstant<Category::Real>, ScalarConstant<Category::Complex>,
|
||||
ScalarConstant<Category::Character>, ScalarConstant<Category::Logical>>
|
||||
std::variant<ScalarConstant<TypeCategory::Integer>,
|
||||
ScalarConstant<TypeCategory::Real>, ScalarConstant<TypeCategory::Complex>,
|
||||
ScalarConstant<TypeCategory::Character>,
|
||||
ScalarConstant<TypeCategory::Logical>>
|
||||
u;
|
||||
};
|
||||
|
||||
// Represents a type of any supported kind within a particular category.
|
||||
template<Category CAT> struct AnyKindType {
|
||||
static constexpr Category category{CAT};
|
||||
template<TypeCategory CAT> struct AnyKindType {
|
||||
static constexpr TypeCategory category{CAT};
|
||||
using Value = ScalarConstant<CAT>;
|
||||
};
|
||||
} // namespace Fortran::evaluate
|
||||
|
|
|
@ -119,8 +119,7 @@ struct GenericExpr;
|
|||
WRAPPER_CLASS_BOILERPLATE(classname, type); \
|
||||
}
|
||||
|
||||
namespace Fortran {
|
||||
namespace parser {
|
||||
namespace Fortran::parser {
|
||||
|
||||
// These are the unavoidable recursively-defined productions of Fortran.
|
||||
// Some references to the representations of their parses require
|
||||
|
@ -3701,6 +3700,5 @@ struct OpenMPConstruct {
|
|||
u;
|
||||
};
|
||||
|
||||
} // namespace parser
|
||||
} // namespace Fortran
|
||||
} // namespace Fortran::parser
|
||||
#endif // FORTRAN_PARSER_PARSE_TREE_H_
|
||||
|
|
|
@ -26,14 +26,14 @@ int Descriptor::Establish(TypeCode t, std::size_t elementBytes, void *p,
|
|||
&raw_, p, CFI_attribute_other, t.raw(), elementBytes, rank, extent);
|
||||
}
|
||||
|
||||
int Descriptor::Establish(TypeCode::Form f, int kind, void *p, int rank,
|
||||
const SubscriptValue *extent) {
|
||||
int Descriptor::Establish(
|
||||
TypeCategory c, int kind, void *p, int rank, const SubscriptValue *extent) {
|
||||
std::size_t elementBytes = kind;
|
||||
if (f == TypeCode::Form::Complex) {
|
||||
if (c == TypeCategory::Complex) {
|
||||
elementBytes *= 2;
|
||||
}
|
||||
return ISO::CFI_establish(&raw_, p, CFI_attribute_other,
|
||||
TypeCode(f, kind).raw(), elementBytes, rank, extent);
|
||||
TypeCode(c, kind).raw(), elementBytes, rank, extent);
|
||||
}
|
||||
|
||||
int Descriptor::Establish(
|
||||
|
@ -53,11 +53,11 @@ Descriptor *Descriptor::Create(TypeCode t, std::size_t elementBytes, void *p,
|
|||
return result;
|
||||
}
|
||||
|
||||
Descriptor *Descriptor::Create(TypeCode::Form f, int kind, void *p, int rank,
|
||||
const SubscriptValue *extent) {
|
||||
Descriptor *Descriptor::Create(
|
||||
TypeCategory c, int kind, void *p, int rank, const SubscriptValue *extent) {
|
||||
std::size_t bytes{SizeInBytes(rank)};
|
||||
Descriptor *result{reinterpret_cast<Descriptor *>(new char[bytes])};
|
||||
result->Establish(f, kind, p, rank, extent);
|
||||
result->Establish(c, kind, p, rank, extent);
|
||||
result->Attributes() |= CREATED;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -108,15 +108,15 @@ public:
|
|||
|
||||
int Establish(TypeCode t, std::size_t elementBytes, void *p = nullptr,
|
||||
int rank = maxRank, const SubscriptValue *extent = nullptr);
|
||||
int Establish(TypeCode::Form f, int kind, void *p = nullptr,
|
||||
int rank = maxRank, const SubscriptValue *extent = nullptr);
|
||||
int Establish(TypeCategory, int kind, void *p = nullptr, int rank = maxRank,
|
||||
const SubscriptValue *extent = nullptr);
|
||||
int Establish(const DerivedType &dt, void *p = nullptr, int rank = maxRank,
|
||||
const SubscriptValue *extent = nullptr);
|
||||
|
||||
static Descriptor *Create(TypeCode t, std::size_t elementBytes,
|
||||
void *p = nullptr, int rank = maxRank,
|
||||
const SubscriptValue *extent = nullptr);
|
||||
static Descriptor *Create(TypeCode::Form f, int kind, void *p = nullptr,
|
||||
static Descriptor *Create(TypeCategory, int kind, void *p = nullptr,
|
||||
int rank = maxRank, const SubscriptValue *extent = nullptr);
|
||||
static Descriptor *Create(const DerivedType &dt, void *p = nullptr,
|
||||
int rank = maxRank, const SubscriptValue *extent = nullptr);
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
|
||||
namespace Fortran::runtime {
|
||||
|
||||
TypeCode::TypeCode(TypeCode::Form f, int kind) {
|
||||
TypeCode::TypeCode(TypeCategory f, int kind) {
|
||||
switch (f) {
|
||||
case Form::Integer:
|
||||
case TypeCategory::Integer:
|
||||
switch (kind) {
|
||||
case 1: raw_ = CFI_type_int8_t; break;
|
||||
case 2: raw_ = CFI_type_int16_t; break;
|
||||
|
@ -27,7 +27,7 @@ TypeCode::TypeCode(TypeCode::Form f, int kind) {
|
|||
case 16: raw_ = CFI_type_int128_t; break;
|
||||
}
|
||||
break;
|
||||
case Form::Real:
|
||||
case TypeCategory::Real:
|
||||
switch (kind) {
|
||||
case 4: raw_ = CFI_type_float; break;
|
||||
case 8: raw_ = CFI_type_double; break;
|
||||
|
@ -35,7 +35,7 @@ TypeCode::TypeCode(TypeCode::Form f, int kind) {
|
|||
case 16: raw_ = CFI_type_long_double; break;
|
||||
}
|
||||
break;
|
||||
case Form::Complex:
|
||||
case TypeCategory::Complex:
|
||||
switch (kind) {
|
||||
case 4: raw_ = CFI_type_float_Complex; break;
|
||||
case 8: raw_ = CFI_type_double_Complex; break;
|
||||
|
@ -43,12 +43,12 @@ TypeCode::TypeCode(TypeCode::Form f, int kind) {
|
|||
case 16: raw_ = CFI_type_long_double_Complex; break;
|
||||
}
|
||||
break;
|
||||
case Form::Character:
|
||||
case TypeCategory::Character:
|
||||
if (kind == 1) {
|
||||
raw_ = CFI_type_cptr;
|
||||
}
|
||||
break;
|
||||
case Form::Logical:
|
||||
case TypeCategory::Logical:
|
||||
switch (kind) {
|
||||
case 1: raw_ = CFI_type_Bool; break;
|
||||
case 2: raw_ = CFI_type_int16_t; break;
|
||||
|
@ -56,7 +56,7 @@ TypeCode::TypeCode(TypeCode::Form f, int kind) {
|
|||
case 8: raw_ = CFI_type_int64_t; break;
|
||||
}
|
||||
break;
|
||||
case Form::Derived: raw_ = CFI_type_struct; break;
|
||||
case TypeCategory::Derived: raw_ = CFI_type_struct; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,16 +16,17 @@
|
|||
#define FORTRAN_RUNTIME_TYPE_CODE_H_
|
||||
|
||||
#include "../include/flang/ISO_Fortran_binding.h"
|
||||
#include "../lib/common/fortran.h"
|
||||
|
||||
namespace Fortran::runtime {
|
||||
|
||||
using common::TypeCategory;
|
||||
|
||||
class TypeCode {
|
||||
public:
|
||||
enum class Form { Integer, Real, Complex, Character, Logical, Derived };
|
||||
|
||||
TypeCode() {}
|
||||
explicit TypeCode(ISO::CFI_type_t t) : raw_{t} {}
|
||||
TypeCode(Form, int);
|
||||
TypeCode(TypeCategory, int);
|
||||
|
||||
int raw() const { return raw_; }
|
||||
|
||||
|
@ -48,23 +49,23 @@ public:
|
|||
|
||||
constexpr bool IsIntrinsic() const { return IsValid() && !IsDerived(); }
|
||||
|
||||
constexpr Form GetForm() const {
|
||||
constexpr TypeCategory Categorize() const {
|
||||
if (IsInteger()) {
|
||||
return Form::Integer;
|
||||
return TypeCategory::Integer;
|
||||
}
|
||||
if (IsReal()) {
|
||||
return Form::Real;
|
||||
return TypeCategory::Real;
|
||||
}
|
||||
if (IsComplex()) {
|
||||
return Form::Complex;
|
||||
return TypeCategory::Complex;
|
||||
}
|
||||
if (IsCharacter()) {
|
||||
return Form::Character;
|
||||
return TypeCategory::Character;
|
||||
}
|
||||
if (IsLogical()) {
|
||||
return Form::Logical;
|
||||
return TypeCategory::Logical;
|
||||
}
|
||||
return Form::Derived;
|
||||
return TypeCategory::Derived;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
// limitations under the License.
|
||||
|
||||
#include "../../lib/evaluate/expression.h"
|
||||
#include "../../lib/parser/message.h"
|
||||
#include "testing.h"
|
||||
#include "../../lib/parser/message.h"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
|
@ -32,14 +32,16 @@ int main() {
|
|||
TEST(DefaultIntegerExpr::Result::Dump() == "Integer(4)");
|
||||
MATCH("666", Dump(DefaultIntegerExpr{666}));
|
||||
MATCH("(-1)", Dump(-DefaultIntegerExpr{1}));
|
||||
auto ex1{DefaultIntegerExpr{2} + DefaultIntegerExpr{3} * -DefaultIntegerExpr{4}};
|
||||
auto ex1{
|
||||
DefaultIntegerExpr{2} + DefaultIntegerExpr{3} * -DefaultIntegerExpr{4}};
|
||||
MATCH("(2+(3*(-4)))", Dump(ex1));
|
||||
Fortran::parser::CharBlock src;
|
||||
Fortran::parser::ContextualMessages messages{src, nullptr};
|
||||
FoldingContext context{messages};
|
||||
ex1.Fold(context);
|
||||
MATCH("-10", Dump(ex1));
|
||||
MATCH("(Integer(4)::6.LE.7)", Dump(DefaultIntegerExpr{6} <= DefaultIntegerExpr{7}));
|
||||
MATCH("(Integer(4)::6.LE.7)",
|
||||
Dump(DefaultIntegerExpr{6} <= DefaultIntegerExpr{7}));
|
||||
DefaultIntegerExpr a{1};
|
||||
DefaultIntegerExpr b{2};
|
||||
MATCH("(1/2)", Dump(a / b));
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
template<int KIND> void testKind() {
|
||||
using Type =
|
||||
Fortran::evaluate::Type<Fortran::evaluate::Category::Logical, KIND>;
|
||||
TEST(Type::category == Fortran::evaluate::Category::Logical);
|
||||
Fortran::evaluate::Type<Fortran::common::TypeCategory::Logical, KIND>;
|
||||
TEST(Type::category == Fortran::common::TypeCategory::Logical);
|
||||
TEST(Type::kind == KIND);
|
||||
TEST(!Type::hasLen);
|
||||
using Value = typename Type::Value;
|
||||
|
|
|
@ -19,37 +19,30 @@
|
|||
#include <cstdlib>
|
||||
|
||||
using namespace Fortran::evaluate;
|
||||
using namespace Fortran::common;
|
||||
|
||||
using Real2 = typename Type<Category::Real, 2>::Value;
|
||||
using Real4 = typename Type<Category::Real, 4>::Value;
|
||||
using Real8 = typename Type<Category::Real, 8>::Value;
|
||||
using Real10 = typename Type<Category::Real, 10>::Value;
|
||||
using Real16 = typename Type<Category::Real, 16>::Value;
|
||||
using Integer4 = typename Type<Category::Integer, 4>::Value;
|
||||
using Integer8 = typename Type<Category::Integer, 8>::Value;
|
||||
using Real2 = typename Type<TypeCategory::Real, 2>::Value;
|
||||
using Real4 = typename Type<TypeCategory::Real, 4>::Value;
|
||||
using Real8 = typename Type<TypeCategory::Real, 8>::Value;
|
||||
using Real10 = typename Type<TypeCategory::Real, 10>::Value;
|
||||
using Real16 = typename Type<TypeCategory::Real, 16>::Value;
|
||||
using Integer4 = typename Type<TypeCategory::Integer, 4>::Value;
|
||||
using Integer8 = typename Type<TypeCategory::Integer, 8>::Value;
|
||||
|
||||
void dumpTest() {
|
||||
struct {
|
||||
std::uint64_t raw;
|
||||
const char *expected;
|
||||
} table[] = {
|
||||
{ 0x7f876543, "NaN 0x7f876543" },
|
||||
{ 0x7f800000, "Inf" },
|
||||
{ 0xff800000, "-Inf" },
|
||||
{ 0x00000000, "0.0" },
|
||||
{ 0x80000000, "-0.0" },
|
||||
{ 0x3f800000, "0x1.0p0" },
|
||||
{ 0xbf800000, "-0x1.0p0" },
|
||||
{ 0x40000000, "0x1.0p1" },
|
||||
{ 0x3f000000, "0x1.0p-1" },
|
||||
{ 0x7f7fffff, "0x1.fffffep127" },
|
||||
{ 0x00800000, "0x1.0p-126" },
|
||||
{ 0x00400000, "0x0.8p-127" },
|
||||
{ 0x00000001, "0x0.000002p-127" },
|
||||
{ 0, nullptr }
|
||||
};
|
||||
} table[] = {{0x7f876543, "NaN 0x7f876543"}, {0x7f800000, "Inf"},
|
||||
{0xff800000, "-Inf"}, {0x00000000, "0.0"}, {0x80000000, "-0.0"},
|
||||
{0x3f800000, "0x1.0p0"}, {0xbf800000, "-0x1.0p0"},
|
||||
{0x40000000, "0x1.0p1"}, {0x3f000000, "0x1.0p-1"},
|
||||
{0x7f7fffff, "0x1.fffffep127"}, {0x00800000, "0x1.0p-126"},
|
||||
{0x00400000, "0x0.8p-127"}, {0x00000001, "0x0.000002p-127"},
|
||||
{0, nullptr}};
|
||||
for (int j{0}; table[j].expected != nullptr; ++j) {
|
||||
TEST(Real4{Integer4{table[j].raw}}.DumpHexadecimal() == table[j].expected)("%d", j);
|
||||
TEST(Real4{Integer4{table[j].raw}}.DumpHexadecimal() == table[j].expected)
|
||||
("%d", j);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue