FLANG
dump-expr.h
1//===-- Semantics/dump-expr.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_SEMANTICS_DUMPEXPR_H
10#define FORTRAN_SEMANTICS_DUMPEXPR_H
11
12#include "flang/Evaluate/tools.h"
13#include "flang/Semantics/symbol.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/ADT/Twine.h"
16
17#include <memory>
18#include <optional>
19#include <string>
20#include <variant>
21#include <vector>
22
23namespace Fortran::semantics {
24
28class DumpEvaluateExpr {
29public:
30 DumpEvaluateExpr() : outs_(llvm::errs()) {}
31 DumpEvaluateExpr(llvm::raw_ostream &str) : outs_(str) {}
32
33 template <typename A> static void Dump(const A &x) {
34 DumpEvaluateExpr{}.Show(x);
35 }
36 template <typename A>
37 static void Dump(llvm::raw_ostream &stream, const A &x) {
38 DumpEvaluateExpr{stream}.Show(x);
39 }
40
41private:
42 template <typename T> struct TypeOf {
43 static constexpr std::string_view get() {
44#if defined(__GNUC__)
45#define DUMP_EXPR_SHOW_TYPE
46 std::string_view v(__PRETTY_FUNCTION__);
47 // Extract the "xyz" from the "pretty function" string:
48 // "... [with T = xyz; std::string_view = ...]"
49#ifdef __clang__
50 std::string_view front("[T = ");
51 std::string_view back("]");
52#else
53 std::string_view front("[with T = ");
54 std::string_view back("; std::string_view =");
55#endif
56
57#elif defined(_MSC_VER)
58#define DUMP_EXPR_SHOW_TYPE
59 std::string_view v(__FUNCSIG__);
60 // Extract the "xyz" from the "pretty function" string:
61 // "...TypeOf<xyz>::get(void)"
62 std::string_view front("TypeOf<");
63 std::string_view back(">::get(void)");
64
65#endif
66
67#if defined(DUMP_EXPR_SHOW_TYPE)
68#undef DUMP_EXPR_SHOW_TYPE
69 if (auto fpos{v.find(front)}; fpos != v.npos) {
70 v.remove_prefix(fpos + front.size());
71 if (auto bpos{v.find(back)}; bpos != v.npos) {
72 v.remove_suffix(v.size() - bpos);
73 return v;
74 }
75 }
76#endif
77 return "";
78 }
79
80 static constexpr std::string_view name{TypeOf<T>::get()};
81 };
82
83 template <typename A, bool C> void Show(const common::Indirection<A, C> &x) {
84 Show(x.value());
85 }
86 template <typename A> void Show(const SymbolRef x) { Show(*x); }
87 template <typename A> void Show(const std::unique_ptr<A> &x) {
88 Show(x.get());
89 }
90 template <typename A> void Show(const std::shared_ptr<A> &x) {
91 Show(x.get());
92 }
93 template <typename A> void Show(const A *x) {
94 if (x) {
95 Show(*x);
96 return;
97 }
98 Print("nullptr");
99 }
100 template <typename A> void Show(const std::optional<A> &x) {
101 if (x) {
102 Show(*x);
103 return;
104 }
105 Print("None");
106 }
107 template <typename... A> void Show(const std::variant<A...> &u) {
108 common::visit([&](const auto &v) { Show(v); }, u);
109 }
110 template <typename A> void Show(const std::vector<A> &x) {
111 Indent("vector");
112 for (const auto &v : x) {
113 Show(v);
114 }
115 Outdent();
116 }
117 void Show(const evaluate::BOZLiteralConstant &);
118 void Show(const evaluate::NullPointer &);
119 template <typename T> void Show(const evaluate::Constant<T> &x) {
120 if constexpr (T::category == common::TypeCategory::Derived) {
121 Indent("derived constant "s + std::string(TypeOf<T>::name));
122 for (const auto &map : x.values()) {
123 for (const auto &pair : map) {
124 Show(pair.second.value());
125 }
126 }
127 Outdent();
128 } else {
129 Print("constant "s + std::string(TypeOf<T>::name));
130 }
131 }
132 void Show(const Symbol &symbol);
133 void Show(const evaluate::StaticDataObject &);
134 void Show(const evaluate::ImpliedDoIndex &);
135 void Show(const evaluate::BaseObject &x);
136 void Show(const evaluate::Component &x);
137 void Show(const evaluate::NamedEntity &x);
138 void Show(const evaluate::TypeParamInquiry &x);
139 void Show(const evaluate::Triplet &x);
140 void Show(const evaluate::Subscript &x);
141 void Show(const evaluate::ArrayRef &x);
142 void Show(const evaluate::CoarrayRef &x);
143 void Show(const evaluate::DataRef &x);
144 void Show(const evaluate::Substring &x);
145 void Show(const evaluate::ComplexPart &x);
146 template <typename T> void Show(const evaluate::Designator<T> &x) {
147 Indent("designator "s + std::string(TypeOf<T>::name));
148 Show(x.u);
149 Outdent();
150 }
151 void Show(const evaluate::DescriptorInquiry &x);
152 void Show(const evaluate::SpecificIntrinsic &);
153 void Show(const evaluate::ProcedureDesignator &x);
154 void Show(const evaluate::ActualArgument &x);
155 void Show(const evaluate::ProcedureRef &x) {
156 Indent("procedure ref");
157 Show(x.proc());
158 Show(x.arguments());
159 Outdent();
160 }
161 template <typename T> void Show(const evaluate::FunctionRef<T> &x) {
162 Indent("function ref "s + std::string(TypeOf<T>::name));
163 Show(x.proc());
164 Show(x.arguments());
165 Outdent();
166 }
167 template <typename T> void Show(const evaluate::ArrayConstructorValue<T> &x) {
168 Show(x.u);
169 }
170 template <typename T>
171 void Show(const evaluate::ArrayConstructorValues<T> &x) {
172 Indent("array constructor value "s + std::string(TypeOf<T>::name));
173 for (auto &v : x) {
174 Show(v);
175 }
176 Outdent();
177 }
178 template <typename T> void Show(const evaluate::ImpliedDo<T> &x) {
179 Indent("implied do "s + std::string(TypeOf<T>::name));
180 Show(x.lower());
181 Show(x.upper());
182 Show(x.stride());
183 Show(x.values());
184 Outdent();
185 }
186 void Show(const ParamValue &x);
187 void Show(const DerivedTypeSpec::ParameterMapType::value_type &x);
188 void Show(const DerivedTypeSpec &x);
189 void Show(const evaluate::StructureConstructorValues::value_type &x);
190 void Show(const evaluate::StructureConstructor &x);
191 template <typename D, typename R, typename O>
192 void Show(const evaluate::Operation<D, R, O> &op) {
193 Indent("unary op "s + std::string(TypeOf<D>::name));
194 Show(op.left());
195 Outdent();
196 }
197 template <typename D, typename R, typename LO, typename RO>
198 void Show(const evaluate::Operation<D, R, LO, RO> &op) {
199 Indent("binary op "s + std::string(TypeOf<D>::name));
200 Show(op.left());
201 Show(op.right());
202 Outdent();
203 }
205 template <typename T> void Show(const evaluate::Expr<T> &x) {
206 Indent("expr <" + std::string(TypeOf<T>::name) + ">");
207 Show(x.u);
208 Outdent();
209 }
210
211 const char *GetIndentString() const;
212 void Print(llvm::Twine s);
213 void Indent(llvm::StringRef s);
214 void Outdent();
215
216 llvm::raw_ostream &outs_;
217 unsigned level_{0};
218};
219
220LLVM_DUMP_METHOD void DumpEvExpr(const evaluate::Expr<evaluate::SomeType> &x);
221LLVM_DUMP_METHOD void DumpEvExpr(
223LLVM_DUMP_METHOD void DumpEvExpr(
225LLVM_DUMP_METHOD void DumpEvExpr(const evaluate::ArrayRef &x);
226LLVM_DUMP_METHOD void DumpEvExpr(const evaluate::DataRef &x);
227LLVM_DUMP_METHOD void DumpEvExpr(const evaluate::Substring &x);
228LLVM_DUMP_METHOD void DumpEvExpr(
230 &x);
231
232} // namespace Fortran::semantics
233
234#endif // FORTRAN_SEMANTICS_DUMPEXPR_H
Definition indirection.h:31
Definition variable.h:205
Definition variable.h:243
Definition variable.h:353
Definition variable.h:73
Definition constant.h:147
Definition variable.h:409
Definition variable.h:377
Definition common.h:214
Definition call.h:293
Definition expression.h:404
Definition variable.h:101
Definition expression.h:114
Definition call.h:233
Definition expression.h:656
Definition static-data.h:29
Definition expression.h:740
Definition variable.h:300
Definition variable.h:160
Definition variable.h:136
Definition type.h:57
Definition type.h:96
Definition symbol.h:791
Definition expression.h:432
Definition variable.h:50
Definition variable.h:284
Definition expression.h:396
Definition expression.h:827
Definition variable.h:191