From 958e4e691e73feb76486f95244e0f26016fd15ee Mon Sep 17 00:00:00 2001 From: Jean Perier Date: Fri, 24 May 2019 01:03:03 -0700 Subject: [PATCH] [flang] checkpoint character intrinsic folding Original-commit: flang-compiler/f18@f495ed92bd1291b6efdb378da79f8f0a9741e15e Reviewed-on: https://github.com/flang-compiler/f18/pull/471 Tree-same-pre-rewrite: false --- flang/lib/evaluate/fold.cc | 49 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/flang/lib/evaluate/fold.cc b/flang/lib/evaluate/fold.cc index cb5185f..9d441a6 100644 --- a/flang/lib/evaluate/fold.cc +++ b/flang/lib/evaluate/fold.cc @@ -13,6 +13,7 @@ // limitations under the License. #include "fold.h" +#include "character.h" #include "characteristics.h" #include "common.h" #include "constant.h" @@ -76,7 +77,6 @@ Expr> FoldOperation( template Expr> FoldOperation( FoldingContext &context, FunctionRef> &&); -// TODO: Character intrinsic function folding template Expr> FoldOperation( FoldingContext &context, FunctionRef> &&); @@ -874,6 +874,53 @@ Expr> FoldOperation(FoldingContext &context, return Expr{std::move(funcRef)}; } +template +Expr> FoldOperation(FoldingContext &context, + FunctionRef> &&funcRef) { + using T = Type; + ActualArguments &args{funcRef.arguments()}; + for (std::optional &arg : args) { + if (arg.has_value()) { + if (auto *expr{arg->GetExpr()}) { + *expr = FoldOperation(context, std::move(*expr)); + } + } + } + if (auto *intrinsic{std::get_if(&funcRef.proc().u)}) { + std::string name{intrinsic->name}; + if (name == "achar") { + // TODO + } else if (name == "char") { + if (auto *sn{UnwrapArgument(args[0])}) { + return std::visit( + [&funcRef, &context](const auto &n) -> Expr { + using IntT = typename std::decay_t::Result; + return FoldElementalIntrinsic(context, + std::move(funcRef), + ScalarFunc([&context](const Scalar &i) { + std::int64_t code{i.ToInt64()}; + if (auto result{CodeToChar(code)}) { + return *result; + } else { + context.messages().Say( + "Character code %lld is invalid for CHARACTER(%d) type"_en_US, + code, KIND); + return CodeToChar(0).value(); + } + })); + }, + sn->u); + } else { + common::die("expected integer argument in CHAR"); + } + } + // TODO: achar, adjustl, adjustr, char, cshift, eoshift, max, maxval, merge, + // min, minval, pack, reduce, repeat, reshape, spread, transfer, transpose, + // trim, unpack + } + return Expr{std::move(funcRef)}; +} + // Get the value of a PARAMETER template std::optional> GetParameterValue( -- 2.7.4