From e67f6a775ec2fb0e1f2878b3eaff6e507e8f47e8 Mon Sep 17 00:00:00 2001 From: Tim Keith Date: Fri, 22 Nov 2019 14:58:26 -0800 Subject: [PATCH] [flang] Extract Parenthesize function Move the code to parenthesize an expression from `ExpressionAnalyzer` into `evaluate/tools.h` so that it can be used to parenthesize an `ActualArgument`. This will be needed for defined assignment calls. Original-commit: flang-compiler/f18@6180d1fb9bd8dbbf26697353b271deb59aa466fa Reviewed-on: https://github.com/flang-compiler/f18/pull/841 Tree-same-pre-rewrite: false --- flang/lib/evaluate/call.cc | 5 +++++ flang/lib/evaluate/call.h | 3 +++ flang/lib/evaluate/tools.cc | 19 +++++++++++++++++++ flang/lib/evaluate/tools.h | 2 ++ flang/lib/semantics/expression.cc | 18 +----------------- 5 files changed, 30 insertions(+), 17 deletions(-) diff --git a/flang/lib/evaluate/call.cc b/flang/lib/evaluate/call.cc index b33a7c6..0292cad 100644 --- a/flang/lib/evaluate/call.cc +++ b/flang/lib/evaluate/call.cc @@ -63,6 +63,11 @@ bool ActualArgument::operator==(const ActualArgument &that) const { isAlternateReturn == that.isAlternateReturn && u_ == that.u_; } +void ActualArgument::Parenthesize() { + CHECK(!isAlternateReturn); + u_ = evaluate::Parenthesize(std::move(DEREF(UnwrapExpr()))); +} + SpecificIntrinsic::SpecificIntrinsic( IntrinsicProcedure n, characteristics::Procedure &&chars) : name{n}, characteristics{new characteristics::Procedure{std::move(chars)}} { diff --git a/flang/lib/evaluate/call.h b/flang/lib/evaluate/call.h index 97edef1..a9db174 100644 --- a/flang/lib/evaluate/call.h +++ b/flang/lib/evaluate/call.h @@ -113,6 +113,9 @@ public: bool Matches(const characteristics::DummyArgument &) const; + // Wrap this argument in parentheses + void Parenthesize(); + // TODO: Mark legacy %VAL and %REF arguments private: diff --git a/flang/lib/evaluate/tools.cc b/flang/lib/evaluate/tools.cc index 5d01747..18e34ef 100644 --- a/flang/lib/evaluate/tools.cc +++ b/flang/lib/evaluate/tools.cc @@ -24,6 +24,25 @@ using namespace Fortran::parser::literals; namespace Fortran::evaluate { +Expr Parenthesize(Expr &&expr) { + return std::visit( + [&](auto &&x) { + using T = std::decay_t; + if constexpr (common::HasMember || + std::is_same_v>) { + return expr; // no parentheses around typeless or derived type + } else { + return std::visit( + [](auto &&y) { + using T = ResultType; + return AsGenericExpr(Parentheses{std::move(y)}); + }, + std::move(x.u)); + } + }, + std::move(expr.u)); +} + // IsVariable() auto IsVariableHelper::operator()(const ProcedureDesignator &x) const -> Result { diff --git a/flang/lib/evaluate/tools.h b/flang/lib/evaluate/tools.h index 719cb4f..44932ac 100644 --- a/flang/lib/evaluate/tools.h +++ b/flang/lib/evaluate/tools.h @@ -153,6 +153,8 @@ common::IfNoLvalue::category>>, A> AsCategoryExpr( inline Expr AsGenericExpr(Expr &&x) { return std::move(x); } +Expr Parenthesize(Expr &&); + Expr GetComplexPart( const Expr &, bool isImaginary = false); diff --git a/flang/lib/semantics/expression.cc b/flang/lib/semantics/expression.cc index 88e92c3..0a08912 100644 --- a/flang/lib/semantics/expression.cc +++ b/flang/lib/semantics/expression.cc @@ -1835,23 +1835,7 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Expr::Parentheses &x) { } } } - return std::visit( - [&](auto &&x) -> MaybeExpr { - using xTy = std::decay_t; - if constexpr (common::HasMember) { - return operand; // ignore parentheses around typeless - } else if constexpr (std::is_same_v>) { - return operand; // ignore parentheses around derived type - } else { - return std::visit( - [](auto &&y) -> MaybeExpr { - using Ty = ResultType; - return {AsGenericExpr(Parentheses{std::move(y)})}; - }, - std::move(x.u)); - } - }, - std::move(operand->u)); + return Parenthesize(std::move(*operand)); } return std::nullopt; } -- 2.7.4