23 #ifndef LLVM_SUPPORT_GRAPHWRITER_H
24 #define LLVM_SUPPORT_GRAPHWRITER_H
42 namespace GraphProgram {
55 template<
typename GraphType>
60 typedef DOTGraphTraits<GraphType> DOTTraits;
61 typedef GraphTraits<GraphType> GTraits;
63 typedef typename GTraits::nodes_iterator node_iterator;
64 typedef typename GTraits::ChildIteratorType child_iterator;
69 bool getEdgeSourceLabels(raw_ostream &O, NodeType *Node) {
70 child_iterator EI = GTraits::child_begin(Node);
71 child_iterator EE = GTraits::child_end(Node);
72 bool hasEdgeSourceLabels =
false;
74 for (
unsigned i = 0; EI != EE && i != 64; ++EI, ++i) {
80 hasEdgeSourceLabels =
true;
88 if (EI != EE && hasEdgeSourceLabels)
89 O <<
"|<s64>truncated...";
91 return hasEdgeSourceLabels;
118 else if (!GraphName.empty())
121 O <<
"digraph unnamed {\n";
124 O <<
"\trankdir=\"BT\";\n";
128 else if (!GraphName.empty())
141 for (node_iterator
I = GTraits::nodes_begin(G), E = GTraits::nodes_end(G);
170 O <<
"\tNode" <<
static_cast<const void*
>(Node) <<
" [shape=record,";
171 if (!NodeAttributes.empty()) O << NodeAttributes <<
",";
179 O <<
"|" << static_cast<const void*>(Node);
182 if (!NodeDesc.empty())
186 std::string edgeSourceLabels;
188 bool hasEdgeSourceLabels = getEdgeSourceLabels(EdgeSourceLabels, Node);
190 if (hasEdgeSourceLabels) {
193 O <<
"{" << EdgeSourceLabels.
str() <<
"}";
203 O <<
"|" << static_cast<const void*>(Node);
206 if (!NodeDesc.empty())
214 for (; i != e && i != 64; ++i) {
216 O <<
"<d" << i <<
">"
221 O <<
"|<d64>truncated...";
228 child_iterator EI = GTraits::child_begin(Node);
229 child_iterator EE = GTraits::child_end(Node);
230 for (
unsigned i = 0; EI != EE && i != 64; ++EI, ++i)
233 for (; EI != EE; ++EI)
238 void writeEdge(NodeType *Node,
unsigned edgeidx, child_iterator EI) {
239 if (NodeType *TargetNode = *EI) {
246 (
unsigned)std::distance(GTraits::child_begin(TargetNode), TargetIt);
247 DestPort =
static_cast<int>(Offset);
253 emitEdge(static_cast<const void*>(Node), edgeidx,
254 static_cast<const void*>(TargetNode), DestPort,
261 const std::string &
Label,
unsigned NumEdgeSources = 0,
262 const std::vector<std::string> *EdgeSourceLabels =
nullptr) {
263 O <<
"\tNode" << ID <<
"[ ";
267 if (NumEdgeSources) O <<
"{";
269 if (NumEdgeSources) {
272 for (
unsigned i = 0; i != NumEdgeSources; ++i) {
274 O <<
"<s" << i <<
">";
283 void emitEdge(
const void *SrcNodeID,
int SrcNodePort,
284 const void *DestNodeID,
int DestNodePort,
285 const std::string &Attrs) {
286 if (SrcNodePort > 64)
return;
287 if (DestNodePort > 64) DestNodePort = 64;
289 O <<
"\tNode" << SrcNodeID;
290 if (SrcNodePort >= 0)
291 O <<
":s" << SrcNodePort;
292 O <<
" -> Node" << DestNodeID;
294 O <<
":d" << DestNodePort;
297 O <<
"[" << Attrs <<
"]";
308 template<
typename GraphType>
310 bool ShortNames =
false,
311 const Twine &Title =
"") {
316 W.writeGraph(Title.str());
323 template <
typename GraphType>
325 bool ShortNames =
false,
const Twine &Title =
"") {
328 std::string
N = Name.
str();
329 N = N.substr(0, std::min<std::size_t>(N.size(), 140));
334 errs() <<
"error opening file '" << Filename <<
"' for writing!\n";
339 errs() <<
" done. \n";
347 template<
typename GraphType>
349 bool ShortNames =
false,
const Twine &Title =
"",
353 if (Filename.empty())
static std::string getNodeDescription(const void *, const GraphType &)
static EdgeIter getEdgeTarget(const void *, EdgeIter I)
getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is called to determine which outgo...
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool isNodeHidden(NodeType *const *Node)
static void addCustomGraphFeatures(const GraphType &, GraphWriter &)
addCustomGraphFeatures - If a graph is made up of more than just straight-forward nodes and edges...
void writeNode(NodeType &Node)
void emitSimpleNode(const void *ID, const std::string &Attr, const std::string &Label, unsigned NumEdgeSources=0, const std::vector< std::string > *EdgeSourceLabels=nullptr)
emitSimpleNode - Outputs a simple (non-record) node
void writeNode(NodeType *Node)
static std::string getEdgeAttributes(const void *, EdgeIter, const GraphType &)
If you want to override the dot attributes printed for a particular edge, override this method...
raw_ostream & getOStream()
getOStream - Get the raw output stream into the graph file.
std::string str() const
Return the twine contents as a std::string.
static std::string getEdgeSourceLabel(const void *, EdgeIter)
getEdgeSourceLabel - If you want to label the edge source itself, implement this method.
static bool hasEdgeDestLabels()
hasEdgeDestLabels - If this function returns true, the graph is able to provide labels for edge desti...
static unsigned numEdgeDestLabels(const void *)
numEdgeDestLabels - If hasEdgeDestLabels, this function returns the number of incoming edge labels th...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static bool edgeTargetsEdgeSource(const void *, EdgeIter)
edgeTargetsEdgeSource - This method returns true if this outgoing edge should actually target another...
bool isNodeHidden(NodeType &Node)
GraphWriter(raw_ostream &o, const GraphType &g, bool SN)
std::string getNodeLabel(const void *, const GraphType &)
getNodeLabel - Given a node and a pointer to the top level graph, return the label to print in the no...
raw_ostream & WriteGraph(raw_ostream &O, const GraphType &G, bool ShortNames=false, const Twine &Title="")
void writeNode(NodeType *const *Node)
std::string EscapeString(const std::string &Label)
void ViewGraph(const GraphType &G, const Twine &Name, bool ShortNames=false, const Twine &Title="", GraphProgram::Name Program=GraphProgram::DOT)
ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file, then cleanup.
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
GraphType::UnknownGraphTypeError NodeType
std::string createGraphFilename(const Twine &Name, int &FD)
static std::string getEdgeDestLabel(const void *, unsigned)
getEdgeDestLabel - If hasEdgeDestLabels, this function returns the incoming edge label with the given...
static std::string getGraphProperties(const GraphType &)
getGraphProperties - Return any custom properties that should be included in the top level graph stru...
void writeHeader(const std::string &Title)
StringRef getColorString(unsigned NodeNumber)
Get a color string for this node number.
static std::string getNodeAttributes(const void *, const GraphType &)
If you want to specify custom node attributes, this is the place to do so.
static bool isNodeHidden(const void *)
isNodeHidden - If the function returns true, the given node is not displayed in the graph...
A raw_ostream that writes to a file descriptor.
bool DisplayGraph(StringRef Filename, bool wait=true, GraphProgram::Name program=GraphProgram::DOT)
A raw_ostream that writes to an std::string.
static bool hasNodeAddressLabel(const void *, const GraphType &)
hasNodeAddressLabel - If this method returns true, the address of the node is added to the label of t...
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
void writeGraph(const std::string &Title="")
void writeEdge(NodeType *Node, unsigned edgeidx, child_iterator EI)
static bool renderGraphFromBottomUp()
renderGraphFromBottomUp - If this function returns true, the graph is emitted bottom-up instead of to...
static std::string getGraphName(const GraphType &)
getGraphName - Return the label for the graph as a whole.
bool isNodeHidden(NodeType *Node)
void emitEdge(const void *SrcNodeID, int SrcNodePort, const void *DestNodeID, int DestNodePort, const std::string &Attrs)
emitEdge - Output an edge from a simple node into the graph...