1 //===-- Lower/DumpEvaluateExpr.h --------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef FORTRAN_LOWER_DUMPEVALUATEEXPR_H 10 #define FORTRAN_LOWER_DUMPEVALUATEEXPR_H 11 12 #include "flang/Evaluate/tools.h" 13 #include "flang/Lower/Support/Utils.h" 14 #include "llvm/ADT/StringRef.h" 15 #include "llvm/ADT/Twine.h" 16 17 namespace Fortran::lower { 18 19 /// Class to dump Fortran::evaluate::Expr trees out in a user readable way. 20 /// 21 /// FIXME: This can be improved to dump more information in some cases. 22 class DumpEvaluateExpr { 23 public: DumpEvaluateExpr()24 DumpEvaluateExpr() : outs(llvm::errs()) {} DumpEvaluateExpr(llvm::raw_ostream & str)25 DumpEvaluateExpr(llvm::raw_ostream &str) : outs(str) {} 26 27 template <typename A> dump(const A & x)28 static void dump(const A &x) { 29 DumpEvaluateExpr{}.show(x); 30 } 31 template <typename A> dump(llvm::raw_ostream & stream,const A & x)32 static void dump(llvm::raw_ostream &stream, const A &x) { 33 DumpEvaluateExpr{stream}.show(x); 34 } 35 36 private: 37 template <typename A, bool C> show(const Fortran::common::Indirection<A,C> & x)38 void show(const Fortran::common::Indirection<A, C> &x) { 39 show(x.value()); 40 } 41 template <typename A> show(const Fortran::semantics::SymbolRef x)42 void show(const Fortran::semantics::SymbolRef x) { 43 show(*x); 44 } 45 template <typename A> show(const std::unique_ptr<A> & x)46 void show(const std::unique_ptr<A> &x) { 47 show(x.get()); 48 } 49 template <typename A> show(const std::shared_ptr<A> & x)50 void show(const std::shared_ptr<A> &x) { 51 show(x.get()); 52 } 53 template <typename A> show(const A * x)54 void show(const A *x) { 55 if (x) { 56 show(*x); 57 return; 58 } 59 print("nullptr"); 60 } 61 template <typename A> show(const std::optional<A> & x)62 void show(const std::optional<A> &x) { 63 if (x) { 64 show(*x); 65 return; 66 } 67 print("None"); 68 } 69 template <typename... A> show(const std::variant<A...> & u)70 void show(const std::variant<A...> &u) { 71 Fortran::common::visit([&](const auto &v) { show(v); }, u); 72 } 73 template <typename A> show(const std::vector<A> & x)74 void show(const std::vector<A> &x) { 75 indent("vector"); 76 for (const auto &v : x) 77 show(v); 78 outdent(); 79 } 80 void show(const Fortran::evaluate::BOZLiteralConstant &); 81 void show(const Fortran::evaluate::NullPointer &); 82 template <typename T> show(const Fortran::evaluate::Constant<T> & x)83 void show(const Fortran::evaluate::Constant<T> &x) { 84 if constexpr (T::category == Fortran::common::TypeCategory::Derived) { 85 indent("derived constant"); 86 for (const auto &map : x.values()) 87 for (const auto &pair : map) 88 show(pair.second.value()); 89 outdent(); 90 } else { 91 print("constant"); 92 } 93 } 94 void show(const Fortran::semantics::Symbol &symbol); 95 void show(const Fortran::evaluate::StaticDataObject &); 96 void show(const Fortran::evaluate::ImpliedDoIndex &); 97 void show(const Fortran::evaluate::BaseObject &x); 98 void show(const Fortran::evaluate::Component &x); 99 void show(const Fortran::evaluate::NamedEntity &x); 100 void show(const Fortran::evaluate::TypeParamInquiry &x); 101 void show(const Fortran::evaluate::Triplet &x); 102 void show(const Fortran::evaluate::Subscript &x); 103 void show(const Fortran::evaluate::ArrayRef &x); 104 void show(const Fortran::evaluate::CoarrayRef &x); 105 void show(const Fortran::evaluate::DataRef &x); 106 void show(const Fortran::evaluate::Substring &x); 107 void show(const Fortran::evaluate::ComplexPart &x); 108 template <typename T> show(const Fortran::evaluate::Designator<T> & x)109 void show(const Fortran::evaluate::Designator<T> &x) { 110 indent("designator"); 111 show(x.u); 112 outdent(); 113 } 114 template <typename T> show(const Fortran::evaluate::Variable<T> & x)115 void show(const Fortran::evaluate::Variable<T> &x) { 116 indent("variable"); 117 show(x.u); 118 outdent(); 119 } 120 void show(const Fortran::evaluate::DescriptorInquiry &x); 121 void show(const Fortran::evaluate::SpecificIntrinsic &); 122 void show(const Fortran::evaluate::ProcedureDesignator &x); 123 void show(const Fortran::evaluate::ActualArgument &x); show(const Fortran::evaluate::ProcedureRef & x)124 void show(const Fortran::evaluate::ProcedureRef &x) { 125 indent("procedure ref"); 126 show(x.proc()); 127 show(x.arguments()); 128 outdent(); 129 } 130 template <typename T> show(const Fortran::evaluate::FunctionRef<T> & x)131 void show(const Fortran::evaluate::FunctionRef<T> &x) { 132 indent("function ref"); 133 show(x.proc()); 134 show(x.arguments()); 135 outdent(); 136 } 137 template <typename T> show(const Fortran::evaluate::ArrayConstructorValue<T> & x)138 void show(const Fortran::evaluate::ArrayConstructorValue<T> &x) { 139 show(x.u); 140 } 141 template <typename T> show(const Fortran::evaluate::ArrayConstructorValues<T> & x)142 void show(const Fortran::evaluate::ArrayConstructorValues<T> &x) { 143 indent("array constructor value"); 144 for (auto &v : x) 145 show(v); 146 outdent(); 147 } 148 template <typename T> show(const Fortran::evaluate::ImpliedDo<T> & x)149 void show(const Fortran::evaluate::ImpliedDo<T> &x) { 150 indent("implied do"); 151 show(x.lower()); 152 show(x.upper()); 153 show(x.stride()); 154 show(x.values()); 155 outdent(); 156 } 157 void show(const Fortran::semantics::ParamValue &x); 158 void 159 show(const Fortran::semantics::DerivedTypeSpec::ParameterMapType::value_type 160 &x); 161 void show(const Fortran::semantics::DerivedTypeSpec &x); 162 void show(const Fortran::evaluate::StructureConstructorValues::value_type &x); 163 void show(const Fortran::evaluate::StructureConstructor &x); 164 template <typename D, typename R, typename O> show(const Fortran::evaluate::Operation<D,R,O> & op)165 void show(const Fortran::evaluate::Operation<D, R, O> &op) { 166 indent("unary op"); 167 show(op.left()); 168 outdent(); 169 } 170 template <typename D, typename R, typename LO, typename RO> show(const Fortran::evaluate::Operation<D,R,LO,RO> & op)171 void show(const Fortran::evaluate::Operation<D, R, LO, RO> &op) { 172 indent("binary op"); 173 show(op.left()); 174 show(op.right()); 175 outdent(); 176 } 177 void 178 show(const Fortran::evaluate::Relational<Fortran::evaluate::SomeType> &x); 179 template <typename T> show(const Fortran::evaluate::Expr<T> & x)180 void show(const Fortran::evaluate::Expr<T> &x) { 181 indent("expr T"); 182 show(x.u); 183 outdent(); 184 } 185 186 const char *getIndentString() const; 187 void print(llvm::Twine s); 188 void indent(llvm::StringRef s); 189 void outdent(); 190 191 llvm::raw_ostream &outs; 192 unsigned level = 0; 193 }; 194 195 LLVM_DUMP_METHOD void 196 dumpEvExpr(const Fortran::evaluate::Expr<Fortran::evaluate::SomeType> &x); 197 LLVM_DUMP_METHOD void dumpEvExpr( 198 const Fortran::evaluate::Expr< 199 Fortran::evaluate::Type<Fortran::common::TypeCategory::Integer, 4>> &x); 200 LLVM_DUMP_METHOD void dumpEvExpr( 201 const Fortran::evaluate::Expr< 202 Fortran::evaluate::Type<Fortran::common::TypeCategory::Integer, 8>> &x); 203 LLVM_DUMP_METHOD void dumpEvExpr(const Fortran::evaluate::ArrayRef &x); 204 LLVM_DUMP_METHOD void dumpEvExpr(const Fortran::evaluate::DataRef &x); 205 LLVM_DUMP_METHOD void dumpEvExpr(const Fortran::evaluate::Substring &x); 206 LLVM_DUMP_METHOD void dumpEvExpr( 207 const Fortran::evaluate::Designator< 208 Fortran::evaluate::Type<Fortran::common::TypeCategory::Integer, 4>> &x); 209 210 } // namespace Fortran::lower 211 212 #endif // FORTRAN_LOWER_DUMPEVALUATEEXPR_H 213