diff --git a/flang/lib/parser/unparse.cc b/flang/lib/parser/unparse.cc index 89bd665ac9bd..2afdbdd78379 100644 --- a/flang/lib/parser/unparse.cc +++ b/flang/lib/parser/unparse.cc @@ -32,10 +32,11 @@ namespace Fortran::parser { class UnparseVisitor { public: UnparseVisitor(std::ostream &out, int indentationAmount, Encoding encoding, - bool capitalize, bool backslashEscapes, preStatementType *preStatement) + bool capitalize, bool backslashEscapes, preStatementType *preStatement, + TypedExprAsFortran *expr) : out_{out}, indentationAmount_{indentationAmount}, encoding_{encoding}, capitalizeKeywords_{capitalize}, backslashEscapes_{backslashEscapes}, - preStatement_{preStatement} {} + preStatement_{preStatement}, typedExprAsFortran_{expr} {} // In nearly all cases, this code avoids defining Boolean-valued Pre() // callbacks for the parse tree walking framework in favor of two void @@ -807,6 +808,15 @@ public: } // R1001 - R1022 + bool Pre(const Expr &x) { + if (typedExprAsFortran_ != nullptr && x.typedExpr.get() != nullptr) { + // Format the expression representation from semantics + (*typedExprAsFortran_)(out_, *x.typedExpr); + return false; + } else { + return true; + } + } void Unparse(const Expr::Parentheses &x) { Put('('), Walk(x.v), Put(')'); } void Before(const Expr::UnaryPlus &x) { Put("+"); } void Before(const Expr::Negate &x) { Put("-"); } @@ -2560,6 +2570,7 @@ private: bool openmpDirective_{false}; bool backslashEscapes_{false}; preStatementType *preStatement_{nullptr}; + TypedExprAsFortran *typedExprAsFortran_{nullptr}; }; void UnparseVisitor::Put(char ch) { @@ -2626,9 +2637,9 @@ void UnparseVisitor::Word(const std::string &str) { Word(str.c_str()); } void Unparse(std::ostream &out, const Program &program, Encoding encoding, bool capitalizeKeywords, bool backslashEscapes, - preStatementType *preStatement) { - UnparseVisitor visitor{ - out, 1, encoding, capitalizeKeywords, backslashEscapes, preStatement}; + preStatementType *preStatement, TypedExprAsFortran *expr) { + UnparseVisitor visitor{out, 1, encoding, capitalizeKeywords, backslashEscapes, + preStatement, expr}; Walk(program, visitor); visitor.Done(); } diff --git a/flang/lib/parser/unparse.h b/flang/lib/parser/unparse.h index 4031ec6d8bdd..6ff838848549 100644 --- a/flang/lib/parser/unparse.h +++ b/flang/lib/parser/unparse.h @@ -1,4 +1,4 @@ -// Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. +// Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,10 @@ #include #include +namespace Fortran::evaluate { +struct GenericExprWrapper; +} + namespace Fortran::parser { struct Program; @@ -28,10 +32,16 @@ struct Program; using preStatementType = std::function; +// A function to handle unparsing of evaluate::GenericExprWrapper +// rather than original expression parse trees. +using TypedExprAsFortran = + std::function; + /// Convert parsed program to out as Fortran. void Unparse(std::ostream &out, const Program &program, Encoding encoding = Encoding::UTF8, bool capitalizeKeywords = true, - bool backslashEscapes = true, preStatementType *preStatement = nullptr); + bool backslashEscapes = true, preStatementType *preStatement = nullptr, + TypedExprAsFortran *expr = nullptr); } #endif diff --git a/flang/tools/f18/f18.cc b/flang/tools/f18/f18.cc index 23e111fe63b9..89e769d1777b 100644 --- a/flang/tools/f18/f18.cc +++ b/flang/tools/f18/f18.cc @@ -19,6 +19,7 @@ #include "../../lib/FIR/graph-writer.h" #endif #include "../../lib/common/default-kinds.h" +#include "../../lib/evaluate/expression.h" #include "../../lib/parser/characters.h" #include "../../lib/parser/dump-parse-tree.h" #include "../../lib/parser/features.h" @@ -256,9 +257,18 @@ std::string CompileFortran(std::string path, Fortran::parser::Options options, Fortran::parser::DumpTree(std::cout, parseTree); } if (driver.dumpUnparse) { + Fortran::parser::TypedExprAsFortran unparseExpression{ + [](std::ostream &o, const Fortran::evaluate::GenericExprWrapper &x) { + if (x.v.has_value()) { + o << *x.v; + } else { + o << "(bad expression)"; + } + }}; Unparse(std::cout, parseTree, driver.encoding, true /*capitalize*/, options.features.IsEnabled( - Fortran::parser::LanguageFeature::BackslashEscapes)); + Fortran::parser::LanguageFeature::BackslashEscapes), + nullptr /* action before each statement */, &unparseExpression); return {}; } if (driver.parseOnly) {