Power<Result>, Extremum<Result>>;
using Indices = std::conditional_t<KIND == ImpliedDoIndex::Result::kind,
std::tuple<ImpliedDoIndex>, std::tuple<>>;
+ using TypeParamInquiries =
+ std::conditional_t<KIND == TypeParamInquiry::Result::kind,
+ std::tuple<TypeParamInquiry>, std::tuple<>>;
using DescriptorInquiries =
std::conditional_t<KIND == DescriptorInquiry::Result::kind,
std::tuple<DescriptorInquiry>, std::tuple<>>;
using Others = std::tuple<Constant<Result>, ArrayConstructor<Result>,
- TypeParamInquiry<KIND>, Designator<Result>, FunctionRef<Result>>;
+ Designator<Result>, FunctionRef<Result>>;
public:
common::TupleToVariant<common::CombineTuples<Operations, Conversions, Indices,
- DescriptorInquiries, Others>>
+ TypeParamInquiries, DescriptorInquiries, Others>>
u;
};
Result operator()(const ImpliedDoIndex &) const { return Scalar(); }
Result operator()(const DescriptorInquiry &) const { return Scalar(); }
- template <int KIND> Result operator()(const TypeParamInquiry<KIND> &) const {
- return Scalar();
- }
+ Result operator()(const TypeParamInquiry &) const { return Scalar(); }
Result operator()(const BOZLiteralConstant &) const { return Scalar(); }
Result operator()(const StaticDataObject::Pointer &) const {
return Scalar();
return visitor_(x.GetFirstSymbol());
}
}
- template <int KIND> Result operator()(const TypeParamInquiry<KIND> &x) const {
+ Result operator()(const TypeParamInquiry &x) const {
return visitor_(x.base());
}
Result operator()(const Triplet &x) const {
// KIND(x), which is then folded to a constant value.
// "Bare" type parameter references within a derived type definition do
// not have base objects.
-template <int KIND> class TypeParamInquiry {
+class TypeParamInquiry {
public:
- using Result = Type<TypeCategory::Integer, KIND>;
+ using Result = SubscriptInteger;
CLASS_BOILERPLATE(TypeParamInquiry)
TypeParamInquiry(NamedEntity &&x, const Symbol ¶m)
: base_{std::move(x)}, parameter_{param} {}
SymbolRef parameter_;
};
-EXPAND_FOR_EACH_INTEGER_KIND(
- TEMPLATE_INSTANTIATION, extern template class TypeParamInquiry, )
-
// R921 subscript-triplet
class Triplet {
public:
};
#define INSTANTIATE_VARIABLE_TEMPLATES \
- EXPAND_FOR_EACH_INTEGER_KIND( \
- TEMPLATE_INSTANTIATION, template class TypeParamInquiry, ) \
FOR_EACH_SPECIFIC_TYPE(template class Designator, )
} // namespace Fortran::evaluate
#endif // FORTRAN_EVALUATE_VARIABLE_H_
IsConstantExprHelper() : Base{*this} {}
using Base::operator();
- template <int KIND> bool operator()(const TypeParamInquiry<KIND> &inq) const {
+ bool operator()(const TypeParamInquiry &inq) const {
return IsKindTypeParameter(inq.parameter());
}
bool operator()(const semantics::Symbol &symbol) const {
return true;
}
bool operator()(const StaticDataObject &) const { return false; }
- template <int KIND> bool operator()(const TypeParamInquiry<KIND> &) const {
- return false;
- }
+ bool operator()(const TypeParamInquiry &) const { return false; }
bool operator()(const Triplet &x) const {
return IsConstantExpr(x.lower()) && IsConstantExpr(x.upper()) &&
IsConstantExpr(x.stride());
return std::nullopt;
}
- template <int KIND>
- Result operator()(const TypeParamInquiry<KIND> &inq) const {
+ Result operator()(const TypeParamInquiry &inq) const {
if (scope_.IsDerivedType() && !IsConstantExpr(inq) &&
inq.parameter().owner() != scope_) { // C750, C754
return "non-constant reference to a type parameter inquiry not "
return Folder<T>{context}.Folding(std::move(designator));
}
-template <int KIND>
-Expr<Type<TypeCategory::Integer, KIND>> FoldOperation(
- FoldingContext &, TypeParamInquiry<KIND> &&);
+Expr<TypeParamInquiry::Result> FoldOperation(
+ FoldingContext &, TypeParamInquiry &&);
Expr<ImpliedDoIndex::Result> FoldOperation(
FoldingContext &context, ImpliedDoIndex &&);
template <typename T>
}
// Substitute a bare type parameter reference with its value if it has one now
-template <int KIND>
-Expr<Type<TypeCategory::Integer, KIND>> FoldOperation(
- FoldingContext &context, TypeParamInquiry<KIND> &&inquiry) {
- using IntKIND = Type<TypeCategory::Integer, KIND>;
+Expr<TypeParamInquiry::Result> FoldOperation(
+ FoldingContext &context, TypeParamInquiry &&inquiry) {
if (!inquiry.base()) {
// A "bare" type parameter: replace with its value, if that's now known.
if (const auto *pdt{context.pdtInstance()}) {
IsConstantExpr(*details->init()))) {
Expr<SomeInteger> expr{*details->init()};
return Fold(context,
- Expr<IntKIND>{
- Convert<IntKIND, TypeCategory::Integer>(std::move(expr))});
+ ConvertToType<TypeParamInquiry::Result>(std::move(expr)));
}
}
}
if (const auto *value{pdt->FindParameter(inquiry.parameter().name())}) {
if (value->isExplicit()) {
return Fold(context,
- Expr<IntKIND>{Convert<IntKIND, TypeCategory::Integer>(
- Expr<SomeInteger>{value->GetExplicit().value()})});
+ AsExpr(ConvertToType<TypeParamInquiry::Result>(
+ Expr<SomeInteger>{value->GetExplicit().value()})));
}
}
}
}
- return Expr<IntKIND>{std::move(inquiry)};
+ return AsExpr(std::move(inquiry));
}
std::optional<std::int64_t> ToInt64(const Expr<SomeInteger> &expr) {
return EmitVar(o, u);
}
-template <int KIND>
-llvm::raw_ostream &TypeParamInquiry<KIND>::AsFortran(
- llvm::raw_ostream &o) const {
+llvm::raw_ostream &TypeParamInquiry::AsFortran(llvm::raw_ostream &o) const {
if (base_) {
return base_->AsFortran(o) << '%';
}
return !that.IsSymbol() && GetComponent() == that.GetComponent();
}
}
-template <int KIND>
-bool TypeParamInquiry<KIND>::operator==(
- const TypeParamInquiry<KIND> &that) const {
+bool TypeParamInquiry::operator==(const TypeParamInquiry &that) const {
return &*parameter_ == &*that.parameter_ && base_ == that.base_;
}
bool Triplet::operator==(const Triplet &that) const {
//===--------------------------------------------------------------------===//
mlir::Type gen(const Fortran::evaluate::ImpliedDoIndex &) {
- return genFIRType<Fortran::common::TypeCategory::Integer>(
- context, defaultKind<Fortran::common::TypeCategory::Integer>());
+ return genFIRType<Fortran::evaluate::ImpliedDoIndex::Result::category>(
+ context, Fortran::evaluate::ImpliedDoIndex::Result::kind);
}
- template <int KIND>
- mlir::Type gen(const Fortran::evaluate::TypeParamInquiry<KIND> &) {
- return genFIRType<Fortran::common::TypeCategory::Integer, KIND>(context);
+ mlir::Type gen(const Fortran::evaluate::TypeParamInquiry &) {
+ return genFIRType<Fortran::evaluate::TypeParamInquiry::Result::category>(
+ context, Fortran::evaluate::TypeParamInquiry::Result::kind);
}
template <typename A>
return AsGenericExpr(std::move(value.value));
}
-// For use with SearchTypes to create a TypeParamInquiry with the
-// right integer kind.
-struct TypeParamInquiryVisitor {
- using Result = std::optional<Expr<SomeInteger>>;
- using Types = IntegerTypes;
- TypeParamInquiryVisitor(int k, NamedEntity &&b, const Symbol ¶m)
- : kind{k}, base{std::move(b)}, parameter{param} {}
- TypeParamInquiryVisitor(int k, const Symbol ¶m)
- : kind{k}, parameter{param} {}
- template <typename T> Result Test() {
- if (kind == T::kind) {
- return Expr<SomeInteger>{
- Expr<T>{TypeParamInquiry<T::kind>{std::move(base), parameter}}};
- }
- return std::nullopt;
- }
- int kind;
- std::optional<NamedEntity> base;
- const Symbol ¶meter;
-};
-
-static std::optional<Expr<SomeInteger>> MakeBareTypeParamInquiry(
- const Symbol *symbol) {
- if (std::optional<DynamicType> dyType{DynamicType::From(symbol)}) {
- if (dyType->category() == TypeCategory::Integer) {
- return common::SearchTypes(
- TypeParamInquiryVisitor{dyType->kind(), *symbol});
- }
- }
- return std::nullopt;
-}
-
// Names and named constants
MaybeExpr ExpressionAnalyzer::Analyze(const parser::Name &n) {
if (std::optional<int> kind{IsImpliedDo(n.source)}) {
if (ultimate.has<semantics::TypeParamDetails>()) {
// A bare reference to a derived type parameter (within a parameterized
// derived type definition)
- return AsMaybeExpr(MakeBareTypeParamInquiry(&ultimate));
+ return Fold(ConvertToType(
+ ultimate, AsGenericExpr(TypeParamInquiry{std::nullopt, ultimate})));
} else {
if (n.symbol->attrs().test(semantics::Attr::VOLATILE)) {
if (const semantics::Scope *
if (auto *designator{UnwrapExpr<Designator<SomeDerived>>(*dtExpr)}) {
if (std::optional<DynamicType> dyType{DynamicType::From(*sym)}) {
if (dyType->category() == TypeCategory::Integer) {
- return AsMaybeExpr(
- common::SearchTypes(TypeParamInquiryVisitor{dyType->kind(),
- IgnoreAnySubscripts(std::move(*designator)), *sym}));
+ return Fold(ConvertToType(*dyType,
+ AsGenericExpr(TypeParamInquiry{
+ IgnoreAnySubscripts(std::move(*designator)), *sym})));
}
}
Say(name, "Type parameter is not INTEGER"_err_en_US);
!REF: /MainProgram1/ipdt/k
integer, kind :: k
!REF: /MainProgram1/ipdt/k
- !DEF: /MainProgram1/ipdt/x ObjectEntity INTEGER(int(k,kind=8))
+ !DEF: /MainProgram1/ipdt/x ObjectEntity INTEGER(int(int(k,kind=4),kind=8))
integer(kind=k) :: x
end type ipdt
!DEF: /MainProgram1/rpdt DerivedType
!REF: /MainProgram1/rpdt/k
integer, kind :: k
!REF: /MainProgram1/rpdt/k
- !DEF: /MainProgram1/rpdt/x ObjectEntity REAL(int(k,kind=8))
+ !DEF: /MainProgram1/rpdt/x ObjectEntity REAL(int(int(k,kind=4),kind=8))
real(kind=k) :: x
end type rpdt
!DEF: /MainProgram1/zpdt DerivedType
!REF: /MainProgram1/zpdt/k
integer, kind :: k
!REF: /MainProgram1/zpdt/k
- !DEF: /MainProgram1/zpdt/x ObjectEntity COMPLEX(int(k,kind=8))
+ !DEF: /MainProgram1/zpdt/x ObjectEntity COMPLEX(int(int(k,kind=4),kind=8))
complex(kind=k) :: x
end type zpdt
!DEF: /MainProgram1/lpdt DerivedType
!REF: /MainProgram1/lpdt/k
integer, kind :: k
!REF: /MainProgram1/lpdt/k
- !DEF: /MainProgram1/lpdt/x ObjectEntity LOGICAL(int(k,kind=8))
+ !DEF: /MainProgram1/lpdt/x ObjectEntity LOGICAL(int(int(k,kind=4),kind=8))
logical(kind=k) :: x
end type lpdt
!REF: /MainProgram1/ipdt
!integer(2),kind::k2
!integer(4),kind::k4
!integer(8),kind::k8
-!integer(int(k1,kind=8))::j1
-!integer(int(k2,kind=8))::j2
-!integer(int(k4,kind=8))::j4
+!integer(int(int(k1,kind=1),kind=8))::j1
+!integer(int(int(k2,kind=2),kind=8))::j2
+!integer(int(int(k4,kind=4),kind=8))::j4
!integer(k8)::j8
!end type
!type::defaulted(n1,n2,n4,n8)
!integer(1),kind::n1=1_1
-!integer(2),kind::n2=int(int(n1,kind=4)*2_4,kind=2)
-!integer(4),kind::n4=2_4*int(n2,kind=4)
-!integer(8),kind::n8=int(12_4-n4,kind=8)
-!type(capture(k1=n1,k2=n2,k4=n4,k8=n8))::cap
+!integer(2),kind::n2=int(int(int(n1,kind=1),kind=4)*2_4,kind=2)
+!integer(4),kind::n4=2_4*int(int(n2,kind=2),kind=4)
+!integer(8),kind::n8=int(12_4-int(n4,kind=4),kind=8)
+!type(capture(k1=int(n1,kind=1),k2=int(n2,kind=2),k4=int(n4,kind=4),k8=n8))::cap
!end type
!type,extends(defaulted)::extension(k5)
!integer(4),kind::k5=4_4
-!integer(int(k5,kind=8))::j5
+!integer(int(int(k5,kind=4),kind=8))::j5
!end type
!type(capture(k1=1_1,k2=1_2,k4=1_4,k8=1_8))::x1111
!integer(1)::res01_1
!module m
!type::t(k)
!integer(4),kind::k=1_4
-!character(1_4,int(k,kind=8))::a
-!character(3_4,int(k,kind=8))::b
+!character(1_4,int(int(k,kind=4),kind=8))::a
+!character(3_4,int(int(k,kind=4),kind=8))::b
!end type
!type(t(k=1_4)),parameter::p=t(k=1_4)(a="x",b="xx ")
!character(2_4,1),parameter::c2(1_8:3_8)=[CHARACTER(KIND=1,LEN=2)::"x ","xx","xx"]
!module m7
! type :: t(k)
! integer(4), kind :: k
-! real(int(k, kind=8)) :: a
+! real(int(int(k,kind=4),kind=8))::a
! end type
! interface operator(+)
! procedure :: f1
!REF: /f2/fwdpdt/k
integer, kind :: k
!REF: /f2/fwdpdt/k
- !DEF: /f2/fwdpdt/n ObjectEntity INTEGER(int(k,kind=8))
+ !DEF: /f2/fwdpdt/n ObjectEntity INTEGER(int(int(k,kind=4),kind=8))
integer(kind=k) :: n
end type
!DEF: /f2/f2 ObjectEntity TYPE(fwdpdt(k=4_4))
!REF: /s2/fwdpdt/k
integer, kind :: k
!REF: /s2/fwdpdt/k
- !DEF: /s2/fwdpdt/n ObjectEntity INTEGER(int(k,kind=8))
+ !DEF: /s2/fwdpdt/n ObjectEntity INTEGER(int(int(k,kind=4),kind=8))
integer(kind=k) :: n
end type
!REF: /s2/q1