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 Andricvoid 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