xref: /freebsd/contrib/llvm-project/clang/lib/AST/StmtViz.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===--- StmtViz.cpp - Graphviz visualization for Stmt ASTs -----*- C++ -*-===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric //  This file implements Stmt::viewAST, which generates a Graphviz DOT file
10*0b57cec5SDimitry Andric //  that depicts the AST and then calls Graphviz/dot+gv on it.
11*0b57cec5SDimitry Andric //
12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13*0b57cec5SDimitry Andric 
14*0b57cec5SDimitry Andric #include "clang/AST/StmtGraphTraits.h"
15*0b57cec5SDimitry Andric #include "clang/AST/Decl.h"
16*0b57cec5SDimitry Andric #include "llvm/Support/GraphWriter.h"
17*0b57cec5SDimitry Andric 
18*0b57cec5SDimitry Andric using namespace clang;
19*0b57cec5SDimitry Andric 
viewAST() const20*0b57cec5SDimitry Andric void Stmt::viewAST() const {
21*0b57cec5SDimitry Andric #ifndef NDEBUG
22*0b57cec5SDimitry Andric   llvm::ViewGraph(this,"AST");
23*0b57cec5SDimitry Andric #else
24*0b57cec5SDimitry Andric   llvm::errs() << "Stmt::viewAST is only available in debug builds on "
25*0b57cec5SDimitry Andric                << "systems with Graphviz or gv!\n";
26*0b57cec5SDimitry Andric #endif
27*0b57cec5SDimitry Andric }
28*0b57cec5SDimitry Andric 
29*0b57cec5SDimitry Andric namespace llvm {
30*0b57cec5SDimitry Andric template<>
31*0b57cec5SDimitry Andric struct DOTGraphTraits<const Stmt*> : public DefaultDOTGraphTraits {
DOTGraphTraitsllvm::DOTGraphTraits32*0b57cec5SDimitry Andric   DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
33*0b57cec5SDimitry Andric 
getNodeLabelllvm::DOTGraphTraits34*0b57cec5SDimitry Andric   static std::string getNodeLabel(const Stmt* Node, const Stmt* Graph) {
35*0b57cec5SDimitry Andric 
36*0b57cec5SDimitry Andric #ifndef NDEBUG
37*0b57cec5SDimitry Andric     std::string OutSStr;
38*0b57cec5SDimitry Andric     llvm::raw_string_ostream Out(OutSStr);
39*0b57cec5SDimitry Andric 
40*0b57cec5SDimitry Andric     if (Node)
41*0b57cec5SDimitry Andric       Out << Node->getStmtClassName();
42*0b57cec5SDimitry Andric     else
43*0b57cec5SDimitry Andric       Out << "<NULL>";
44*0b57cec5SDimitry Andric 
45*0b57cec5SDimitry Andric     std::string OutStr = Out.str();
46*0b57cec5SDimitry Andric     if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
47*0b57cec5SDimitry Andric 
48*0b57cec5SDimitry Andric     // Process string output to make it nicer...
49*0b57cec5SDimitry Andric     for (unsigned i = 0; i != OutStr.length(); ++i)
50*0b57cec5SDimitry Andric       if (OutStr[i] == '\n') {                            // Left justify
51*0b57cec5SDimitry Andric         OutStr[i] = '\\';
52*0b57cec5SDimitry Andric         OutStr.insert(OutStr.begin()+i+1, 'l');
53*0b57cec5SDimitry Andric       }
54*0b57cec5SDimitry Andric 
55*0b57cec5SDimitry Andric     return OutStr;
56*0b57cec5SDimitry Andric #else
57*0b57cec5SDimitry Andric     return "";
58*0b57cec5SDimitry Andric #endif
59*0b57cec5SDimitry Andric   }
60*0b57cec5SDimitry Andric };
61*0b57cec5SDimitry Andric } // end namespace llvm
62