diff --git a/flang/include/flang/Evaluate/expression.h b/flang/include/flang/Evaluate/expression.h --- a/flang/include/flang/Evaluate/expression.h +++ b/flang/include/flang/Evaluate/expression.h @@ -516,15 +516,18 @@ Power, Extremum>; using Indices = std::conditional_t, std::tuple<>>; + using TypeParamInquiries = + std::conditional_t, std::tuple<>>; using DescriptorInquiries = std::conditional_t, std::tuple<>>; using Others = std::tuple, ArrayConstructor, - TypeParamInquiry, Designator, FunctionRef>; + Designator, FunctionRef>; public: common::TupleToVariant> + TypeParamInquiries, DescriptorInquiries, Others>> u; }; diff --git a/flang/include/flang/Evaluate/shape.h b/flang/include/flang/Evaluate/shape.h --- a/flang/include/flang/Evaluate/shape.h +++ b/flang/include/flang/Evaluate/shape.h @@ -93,9 +93,7 @@ Result operator()(const ImpliedDoIndex &) const { return Scalar(); } Result operator()(const DescriptorInquiry &) const { return Scalar(); } - template Result operator()(const TypeParamInquiry &) 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(); diff --git a/flang/include/flang/Evaluate/traverse.h b/flang/include/flang/Evaluate/traverse.h --- a/flang/include/flang/Evaluate/traverse.h +++ b/flang/include/flang/Evaluate/traverse.h @@ -120,7 +120,7 @@ return visitor_(x.GetFirstSymbol()); } } - template Result operator()(const TypeParamInquiry &x) const { + Result operator()(const TypeParamInquiry &x) const { return visitor_(x.base()); } Result operator()(const Triplet &x) const { diff --git a/flang/include/flang/Evaluate/variable.h b/flang/include/flang/Evaluate/variable.h --- a/flang/include/flang/Evaluate/variable.h +++ b/flang/include/flang/Evaluate/variable.h @@ -128,9 +128,9 @@ // 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 class TypeParamInquiry { +class TypeParamInquiry { public: - using Result = Type; + using Result = SubscriptInteger; CLASS_BOILERPLATE(TypeParamInquiry) TypeParamInquiry(NamedEntity &&x, const Symbol ¶m) : base_{std::move(x)}, parameter_{param} {} @@ -150,9 +150,6 @@ SymbolRef parameter_; }; -EXPAND_FOR_EACH_INTEGER_KIND( - TEMPLATE_INSTANTIATION, extern template class TypeParamInquiry, ) - // R921 subscript-triplet class Triplet { public: @@ -422,8 +419,6 @@ }; #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_ diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp --- a/flang/lib/Evaluate/check-expression.cpp +++ b/flang/lib/Evaluate/check-expression.cpp @@ -29,7 +29,7 @@ IsConstantExprHelper() : Base{*this} {} using Base::operator(); - template bool operator()(const TypeParamInquiry &inq) const { + bool operator()(const TypeParamInquiry &inq) const { return IsKindTypeParameter(inq.parameter()); } bool operator()(const semantics::Symbol &symbol) const { @@ -155,9 +155,7 @@ return true; } bool operator()(const StaticDataObject &) const { return false; } - template bool operator()(const TypeParamInquiry &) 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()); @@ -310,8 +308,7 @@ return std::nullopt; } - template - Result operator()(const TypeParamInquiry &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 " diff --git a/flang/lib/Evaluate/fold-implementation.h b/flang/lib/Evaluate/fold-implementation.h --- a/flang/lib/Evaluate/fold-implementation.h +++ b/flang/lib/Evaluate/fold-implementation.h @@ -115,9 +115,8 @@ return Folder{context}.Folding(std::move(designator)); } -template -Expr> FoldOperation( - FoldingContext &, TypeParamInquiry &&); +Expr FoldOperation( + FoldingContext &, TypeParamInquiry &&); Expr FoldOperation( FoldingContext &context, ImpliedDoIndex &&); template diff --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp --- a/flang/lib/Evaluate/fold-integer.cpp +++ b/flang/lib/Evaluate/fold-integer.cpp @@ -600,10 +600,8 @@ } // Substitute a bare type parameter reference with its value if it has one now -template -Expr> FoldOperation( - FoldingContext &context, TypeParamInquiry &&inquiry) { - using IntKIND = Type; +Expr 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()}) { @@ -617,21 +615,20 @@ IsConstantExpr(*details->init()))) { Expr expr{*details->init()}; return Fold(context, - Expr{ - Convert(std::move(expr))}); + ConvertToType(std::move(expr))); } } } if (const auto *value{pdt->FindParameter(inquiry.parameter().name())}) { if (value->isExplicit()) { return Fold(context, - Expr{Convert( - Expr{value->GetExplicit().value()})}); + AsExpr(ConvertToType( + Expr{value->GetExplicit().value()}))); } } } } - return Expr{std::move(inquiry)}; + return AsExpr(std::move(inquiry)); } std::optional ToInt64(const Expr &expr) { diff --git a/flang/lib/Evaluate/formatting.cpp b/flang/lib/Evaluate/formatting.cpp --- a/flang/lib/Evaluate/formatting.cpp +++ b/flang/lib/Evaluate/formatting.cpp @@ -606,9 +606,7 @@ return EmitVar(o, u); } -template -llvm::raw_ostream &TypeParamInquiry::AsFortran( - llvm::raw_ostream &o) const { +llvm::raw_ostream &TypeParamInquiry::AsFortran(llvm::raw_ostream &o) const { if (base_) { return base_->AsFortran(o) << '%'; } diff --git a/flang/lib/Evaluate/variable.cpp b/flang/lib/Evaluate/variable.cpp --- a/flang/lib/Evaluate/variable.cpp +++ b/flang/lib/Evaluate/variable.cpp @@ -635,9 +635,7 @@ return !that.IsSymbol() && GetComponent() == that.GetComponent(); } } -template -bool TypeParamInquiry::operator==( - const TypeParamInquiry &that) const { +bool TypeParamInquiry::operator==(const TypeParamInquiry &that) const { return &*parameter_ == &*that.parameter_ && base_ == that.base_; } bool Triplet::operator==(const Triplet &that) const { diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp --- a/flang/lib/Lower/ConvertType.cpp +++ b/flang/lib/Lower/ConvertType.cpp @@ -262,13 +262,13 @@ //===--------------------------------------------------------------------===// mlir::Type gen(const Fortran::evaluate::ImpliedDoIndex &) { - return genFIRType( - context, defaultKind()); + return genFIRType( + context, Fortran::evaluate::ImpliedDoIndex::Result::kind); } - template - mlir::Type gen(const Fortran::evaluate::TypeParamInquiry &) { - return genFIRType(context); + mlir::Type gen(const Fortran::evaluate::TypeParamInquiry &) { + return genFIRType( + context, Fortran::evaluate::TypeParamInquiry::Result::kind); } template diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp --- a/flang/lib/Semantics/expression.cpp +++ b/flang/lib/Semantics/expression.cpp @@ -643,38 +643,6 @@ 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>; - 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 Result Test() { - if (kind == T::kind) { - return Expr{ - Expr{TypeParamInquiry{std::move(base), parameter}}}; - } - return std::nullopt; - } - int kind; - std::optional base; - const Symbol ¶meter; -}; - -static std::optional> MakeBareTypeParamInquiry( - const Symbol *symbol) { - if (std::optional 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 kind{IsImpliedDo(n.source)}) { @@ -690,7 +658,8 @@ if (ultimate.has()) { // 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 * @@ -989,9 +958,9 @@ if (auto *designator{UnwrapExpr>(*dtExpr)}) { if (std::optional 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); diff --git a/flang/test/Semantics/kinds03.f90 b/flang/test/Semantics/kinds03.f90 --- a/flang/test/Semantics/kinds03.f90 +++ b/flang/test/Semantics/kinds03.f90 @@ -5,7 +5,7 @@ !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 @@ -14,7 +14,7 @@ !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 @@ -23,7 +23,7 @@ !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 @@ -32,7 +32,7 @@ !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 diff --git a/flang/test/Semantics/modfile17.f90 b/flang/test/Semantics/modfile17.f90 --- a/flang/test/Semantics/modfile17.f90 +++ b/flang/test/Semantics/modfile17.f90 @@ -91,21 +91,21 @@ !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 diff --git a/flang/test/Semantics/modfile22.f90 b/flang/test/Semantics/modfile22.f90 --- a/flang/test/Semantics/modfile22.f90 +++ b/flang/test/Semantics/modfile22.f90 @@ -15,8 +15,8 @@ !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"] diff --git a/flang/test/Semantics/modfile33.f90 b/flang/test/Semantics/modfile33.f90 --- a/flang/test/Semantics/modfile33.f90 +++ b/flang/test/Semantics/modfile33.f90 @@ -608,7 +608,7 @@ !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 diff --git a/flang/test/Semantics/symbol17.f90 b/flang/test/Semantics/symbol17.f90 --- a/flang/test/Semantics/symbol17.f90 +++ b/flang/test/Semantics/symbol17.f90 @@ -80,7 +80,7 @@ !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)) @@ -100,7 +100,7 @@ !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