From d7b3accb325ed6bc9832dd96145e40b4caa088d3 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Thu, 5 Jul 2018 10:47:01 -0700 Subject: [PATCH] [flang] tweaks Original-commit: flang-compiler/f18@624c1d2ec8539ae96f00c99ca90c56a0d7e3d266 Reviewed-on: https://github.com/flang-compiler/f18/pull/117 Tree-same-pre-rewrite: false --- flang/lib/evaluate/expression.cc | 134 +++++++++++++++++++------------------- flang/lib/evaluate/expression.h | 7 +- flang/test/evaluate/expression.cc | 3 +- 3 files changed, 75 insertions(+), 69 deletions(-) diff --git a/flang/lib/evaluate/expression.cc b/flang/lib/evaluate/expression.cc index 88b8b28..834aec7 100644 --- a/flang/lib/evaluate/expression.cc +++ b/flang/lib/evaluate/expression.cc @@ -84,62 +84,6 @@ std::ostream &IntegerExpr::Dump(std::ostream &o) const { return o; } -template -void IntegerExpr::Fold( - const parser::CharBlock &at, parser::Messages *messages) { - std::visit(common::visitors{[&](const Parentheses &p) { - p.x->Fold(at, messages); - if (auto c{std::get_if(&p.x->u)}) { - u = *c; - } - }, - [&](const Negate &n) { - n.x->Fold(at, messages); - if (auto c{std::get_if(&n.x->u)}) { - auto negated{c->Negate()}; - if (negated.overflow && messages != nullptr) { - messages->Say(at, "integer negation overflowed"_en_US); - } - u = negated.value; - } - }, - [&](const Add &a) { - a.x->Fold(at, messages); - a.y->Fold(at, messages); - if (auto xc{std::get_if(&a.x->u)}) { - if (auto yc{std::get_if(&a.y->u)}) { - auto sum{xc->AddSigned(*yc)}; - if (sum.overflow && messages != nullptr) { - messages->Say(at, "integer addition overflowed"_en_US); - } - u = sum.value; - } - } - }, - [&](const Multiply &a) { - a.x->Fold(at, messages); - a.y->Fold(at, messages); - if (auto xc{std::get_if(&a.x->u)}) { - if (auto yc{std::get_if(&a.y->u)}) { - auto product{xc->MultiplySigned(*yc)}; - if (product.SignedMultiplicationOverflowed() && - messages != nullptr) { - messages->Say( - at, "integer multiplication overflowed"_en_US); - } - u = product.lower; - } - } - }, - [&](const Bin &b) { - b.x->Fold(at, messages); - b.y->Fold(at, messages); - }, - [&](const auto &) { // TODO: more - }}, - u); -} - template std::ostream &RealExpr::Dump(std::ostream &o) const { std::visit( common::visitors{[&](const Constant &n) { o << n.DumpHexadecimal(); }, @@ -177,17 +121,6 @@ std::ostream &ComplexExpr::Dump(std::ostream &o) const { } template -typename CharacterExpr::LengthExpr CharacterExpr::LEN() const { - return std::visit( - common::visitors{ - [](const std::string &str) { return LengthExpr{str.size()}; }, - [](const Concat &c) { - return LengthExpr{LengthExpr::Add{c.x->LEN(), c.y->LEN()}}; - }}, - u); -} - -template std::ostream &CharacterExpr::Dump(std::ostream &o) const { std::visit(common::visitors{[&](const Constant &s) { o << '"' << s << '"'; }, [&](const Concat &c) { c.y->Dump(c.x->Dump(o) << "//"); }}, @@ -247,6 +180,73 @@ std::ostream &LogicalExpr::Dump(std::ostream &o) const { return o; } +template void IntegerExpr::Fold(FoldingContext &context) { + std::visit(common::visitors{[&](const Parentheses &p) { + p.x->Fold(context); + if (auto c{std::get_if(&p.x->u)}) { + u = std::move(*c); + } + }, + [&](const Negate &n) { + n.x->Fold(context); + if (auto c{std::get_if(&n.x->u)}) { + auto negated{c->Negate()}; + if (negated.overflow && context.messages != nullptr) { + context.messages->Say( + context.at, "integer negation overflowed"_en_US); + } + u = std::move(negated.value); + } + }, + [&](const Add &a) { + a.x->Fold(context); + a.y->Fold(context); + if (auto xc{std::get_if(&a.x->u)}) { + if (auto yc{std::get_if(&a.y->u)}) { + auto sum{xc->AddSigned(*yc)}; + if (sum.overflow && context.messages != nullptr) { + context.messages->Say( + context.at, "integer addition overflowed"_en_US); + } + u = std::move(sum.value); + } + } + }, + [&](const Multiply &a) { + a.x->Fold(context); + a.y->Fold(context); + if (auto xc{std::get_if(&a.x->u)}) { + if (auto yc{std::get_if(&a.y->u)}) { + auto product{xc->MultiplySigned(*yc)}; + if (product.SignedMultiplicationOverflowed() && + context.messages != nullptr) { + context.messages->Say(context.at, + "integer multiplication overflowed"_en_US); + } + u = std::move(product.lower); + } + } + }, + [&](const Bin &b) { + b.x->Fold(context); + b.y->Fold(context); + }, + [&](const auto &) { // TODO: more + }}, + u); +} + +template +typename CharacterExpr::LengthExpr CharacterExpr::LEN() const { + return std::visit( + common::visitors{ + [](const std::string &str) { return LengthExpr{str.size()}; }, + [](const Concat &c) { + return LengthExpr{LengthExpr::Add{c.x->LEN(), c.y->LEN()}}; + }}, + u); +} + template struct IntegerExpr<1>; template struct IntegerExpr<2>; template struct IntegerExpr<4>; diff --git a/flang/lib/evaluate/expression.h b/flang/lib/evaluate/expression.h index 950e2ae..7cd77a4 100644 --- a/flang/lib/evaluate/expression.h +++ b/flang/lib/evaluate/expression.h @@ -44,6 +44,11 @@ struct AnyRealExpr; struct AnyComplexExpr; struct AnyCharacterExpr; +struct FoldingContext { + const parser::CharBlock &at; + parser::Messages *messages; +}; + // Helper base classes to manage subexpressions, which are known as data members // named 'x' and, for binary operations, 'y'. template struct Unary { @@ -136,7 +141,7 @@ template struct IntegerExpr { IntegerExpr &operator=(IntegerExpr &&) = default; std::ostream &Dump(std::ostream &) const; - void Fold(const parser::CharBlock &, parser::Messages *); + void Fold(FoldingContext &); std::variant, Convert, Parentheses, Negate, Add, Subtract, Multiply, Divide, Power> diff --git a/flang/test/evaluate/expression.cc b/flang/test/evaluate/expression.cc index 682aefd..e33df6b 100644 --- a/flang/test/evaluate/expression.cc +++ b/flang/test/evaluate/expression.cc @@ -34,7 +34,8 @@ int main() { auto ex1{DefaultIntegerExpr{2} + DefaultIntegerExpr{3} * -DefaultIntegerExpr{4}}; MATCH("(2+(3*(-4)))", Dump(ex1)); Fortran::parser::CharBlock src; - ex1.Fold(src, nullptr); + FoldingContext context{src, nullptr}; + ex1.Fold(context); MATCH("-10", Dump(ex1)); MATCH("(6.LE.7)", Dump(DefaultIntegerExpr{6} <= DefaultIntegerExpr{7})); DefaultIntegerExpr a{1}; -- 2.7.4