5#include "llvm/Support/raw_ostream.h"
11static auto xml_escape(std::string_view data) -> std::string {
13 llvm::raw_string_ostream stream(str);
17 case '&': stream <<
"&";
break;
18 case '\'': stream <<
"'";
break;
19 case '\"': stream <<
""";
break;
20 case '<': stream <<
"<";
break;
21 case '>': stream <<
">";
break;
22 case '\0': stream <<
"\\\\0";
break;
23 default: stream << i;
break;
30inline static auto opt_str(
const char* ptr) -> optional<string> {
36auto DotVisitor::add_node(
const string& content,
const char* label) -> DotNode& {
37 return add_node(DotNode(m_index, std::nullopt, std::nullopt, content), label);
40auto DotVisitor::add_node(DotNode&& node,
const char* label) -> DotNode& {
42 if (m_parent ==
nullptr) {
43 m_root = std::make_unique<DotNode>(node);
46 return m_parent->children.emplace_back(
opt_str(label), node).child;
49void DotVisitor::DotNode::write(llvm::raw_ostream& stream)
const {
50 stream << AST_KEY << index <<
" [label=<";
52 stream <<
"<I>" << content <<
"</I>";
54 stream <<
"<FONT POINT-SIZE=\"9\">" << location->to_string() <<
"</FONT><BR/>";
56 stream <<
"<U>" << *type <<
"</U><BR/>";
57 stream <<
"<B>" << content <<
"</B>";
60 bool skip_first_child =
false;
61 if (!children.empty()) {
62 const auto& first = children.at(0);
63 if (!first.line_label.has_value() && first.child.simple()) {
64 skip_first_child =
true;
65 stream <<
"<BR/><I>" << first.child.content <<
"</I>";
71 for (
const auto& [line_label, child] : children) {
72 if (skip_first_child) {
73 skip_first_child =
false;
77 stream << AST_KEY << index <<
" -> " << AST_KEY << child.index;
78 if (line_label.has_value())
79 stream <<
" [label=\"" << *line_label <<
"\"]";
85 Loc location = expr.location();
86 optional<string> type = {};
87 if (
auto val_ty = expr.val_ty(); val_ty)
89 auto kind_label =
xml_escape(expr.kind_name());
91 auto& node = add_node(DotNode(m_index, location, type, kind_label), label.data());
93 auto* restore_parent = std::exchange(m_parent, &node);
95 m_parent = restore_parent;
98 if (restore_parent ==
nullptr) {
113 add_node(
"<FONT COLOR=\"RED\">NULL</FONT>", label.data());
All nodes in the AST tree of the program inherit from this class.
auto visit(const ast::AST &expr, string_view label) -> DotVisitor &override
static auto xml_escape(std::string_view data) -> std::string
static auto opt_str(const char *ptr) -> optional< string >
Represents a location in source code, as a range starting at a line and column and ending at some oth...