//===-- Lower/DumpEvaluateExpr.h --------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef FORTRAN_LOWER_DUMPEVALUATEEXPR_H #define FORTRAN_LOWER_DUMPEVALUATEEXPR_H #include "flang/Evaluate/tools.h" #include "flang/Lower/Support/Utils.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" namespace Fortran::lower { /// Class to dump Fortran::evaluate::Expr trees out in a user readable way. /// /// FIXME: This can be improved to dump more information in some cases. class DumpEvaluateExpr { public: DumpEvaluateExpr() : outs(llvm::errs()) {} DumpEvaluateExpr(llvm::raw_ostream &str) : outs(str) {} template static void dump(const A &x) { DumpEvaluateExpr{}.show(x); } template static void dump(llvm::raw_ostream &stream, const A &x) { DumpEvaluateExpr{stream}.show(x); } private: template void show(const Fortran::common::Indirection &x) { show(x.value()); } template void show(const Fortran::semantics::SymbolRef x) { show(*x); } template void show(const std::unique_ptr &x) { show(x.get()); } template void show(const std::shared_ptr &x) { show(x.get()); } template void show(const A *x) { if (x) { show(*x); return; } print("nullptr"); } template void show(const std::optional &x) { if (x) { show(*x); return; } print("None"); } template void show(const std::variant &u) { std::visit([&](const auto &v) { show(v); }, u); } template void show(const std::vector &x) { indent("vector"); for (const auto &v : x) show(v); outdent(); } void show(const Fortran::evaluate::BOZLiteralConstant &); void show(const Fortran::evaluate::NullPointer &); template void show(const Fortran::evaluate::Constant &x) { if constexpr (T::category == Fortran::common::TypeCategory::Derived) { indent("derived constant"); for (const auto &map : x.values()) for (const auto &pair : map) show(pair.second.value()); outdent(); } else { print("constant"); } } void show(const Fortran::semantics::Symbol &symbol); void show(const Fortran::evaluate::StaticDataObject &); void show(const Fortran::evaluate::ImpliedDoIndex &); void show(const Fortran::evaluate::BaseObject &x); void show(const Fortran::evaluate::Component &x); void show(const Fortran::evaluate::NamedEntity &x); void show(const Fortran::evaluate::TypeParamInquiry &x); void show(const Fortran::evaluate::Triplet &x); void show(const Fortran::evaluate::Subscript &x); void show(const Fortran::evaluate::ArrayRef &x); void show(const Fortran::evaluate::CoarrayRef &x); void show(const Fortran::evaluate::DataRef &x); void show(const Fortran::evaluate::Substring &x); void show(const Fortran::evaluate::ComplexPart &x); template void show(const Fortran::evaluate::Designator &x) { indent("designator"); show(x.u); outdent(); } template void show(const Fortran::evaluate::Variable &x) { indent("variable"); show(x.u); outdent(); } void show(const Fortran::evaluate::DescriptorInquiry &x); void show(const Fortran::evaluate::SpecificIntrinsic &); void show(const Fortran::evaluate::ProcedureDesignator &x); void show(const Fortran::evaluate::ActualArgument &x); void show(const Fortran::evaluate::ProcedureRef &x) { indent("procedure ref"); show(x.proc()); show(x.arguments()); outdent(); } template void show(const Fortran::evaluate::FunctionRef &x) { indent("function ref"); show(x.proc()); show(x.arguments()); outdent(); } template void show(const Fortran::evaluate::ArrayConstructorValue &x) { show(x.u); } template void show(const Fortran::evaluate::ArrayConstructorValues &x) { indent("array constructor value"); for (auto &v : x) show(v); outdent(); } template void show(const Fortran::evaluate::ImpliedDo &x) { indent("implied do"); show(x.lower()); show(x.upper()); show(x.stride()); show(x.values()); outdent(); } void show(const Fortran::semantics::ParamValue &x); void show(const Fortran::semantics::DerivedTypeSpec::ParameterMapType::value_type &x); void show(const Fortran::semantics::DerivedTypeSpec &x); void show(const Fortran::evaluate::StructureConstructorValues::value_type &x); void show(const Fortran::evaluate::StructureConstructor &x); template void show(const Fortran::evaluate::Operation &op) { indent("unary op"); show(op.left()); outdent(); } template void show(const Fortran::evaluate::Operation &op) { indent("binary op"); show(op.left()); show(op.right()); outdent(); } void show(const Fortran::evaluate::Relational &x); template void show(const Fortran::evaluate::Expr &x) { indent("expr T"); show(x.u); outdent(); } const char *getIndentString() const; void print(llvm::Twine s); void indent(llvm::StringRef s); void outdent(); llvm::raw_ostream &outs; unsigned level = 0; }; LLVM_DUMP_METHOD void dumpEvExpr(const Fortran::evaluate::Expr &x); LLVM_DUMP_METHOD void dumpEvExpr( const Fortran::evaluate::Expr< Fortran::evaluate::Type> &x); LLVM_DUMP_METHOD void dumpEvExpr( const Fortran::evaluate::Expr< Fortran::evaluate::Type> &x); LLVM_DUMP_METHOD void dumpEvExpr(const Fortran::evaluate::ArrayRef &x); LLVM_DUMP_METHOD void dumpEvExpr(const Fortran::evaluate::DataRef &x); LLVM_DUMP_METHOD void dumpEvExpr(const Fortran::evaluate::Substring &x); LLVM_DUMP_METHOD void dumpEvExpr( const Fortran::evaluate::Designator< Fortran::evaluate::Type> &x); } // namespace Fortran::lower #endif // FORTRAN_LOWER_DUMPEVALUATEEXPR_H