1 //===-- CFGPrinter.h - CFG printer external interface -----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines external functions that can be called to explicitly 11 // instantiate the CFG printer. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_ANALYSIS_CFGPRINTER_H 16 #define LLVM_ANALYSIS_CFGPRINTER_H 17 18 #include "llvm/Constants.h" 19 #include "llvm/Function.h" 20 #include "llvm/Instructions.h" 21 #include "llvm/Assembly/Writer.h" 22 #include "llvm/Support/CFG.h" 23 #include "llvm/Support/GraphWriter.h" 24 25 namespace llvm { 26 template<> 27 struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits { 28 29 DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} 30 31 static std::string getGraphName(const Function *F) { 32 return "CFG for '" + F->getNameStr() + "' function"; 33 } 34 35 static std::string getSimpleNodeLabel(const BasicBlock *Node, 36 const Function *Graph) { 37 if (!Node->getName().empty()) 38 return Node->getNameStr(); 39 40 std::string Str; 41 raw_string_ostream OS(Str); 42 43 WriteAsOperand(OS, Node, false); 44 return OS.str(); 45 } 46 47 static std::string getCompleteNodeLabel(const BasicBlock *Node, 48 const Function *Graph) { 49 std::string Str; 50 raw_string_ostream OS(Str); 51 52 if (Node->getName().empty()) { 53 WriteAsOperand(OS, Node, false); 54 OS << ":"; 55 } 56 57 OS << *Node; 58 std::string OutStr = OS.str(); 59 if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); 60 61 // Process string output to make it nicer... 62 for (unsigned i = 0; i != OutStr.length(); ++i) 63 if (OutStr[i] == '\n') { // Left justify 64 OutStr[i] = '\\'; 65 OutStr.insert(OutStr.begin()+i+1, 'l'); 66 } else if (OutStr[i] == ';') { // Delete comments! 67 unsigned Idx = OutStr.find('\n', i+1); // Find end of line 68 OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx); 69 --i; 70 } 71 72 return OutStr; 73 } 74 75 std::string getNodeLabel(const BasicBlock *Node, 76 const Function *Graph) { 77 if (isSimple()) 78 return getSimpleNodeLabel(Node, Graph); 79 else 80 return getCompleteNodeLabel(Node, Graph); 81 } 82 83 static std::string getEdgeSourceLabel(const BasicBlock *Node, 84 succ_const_iterator I) { 85 // Label source of conditional branches with "T" or "F" 86 if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator())) 87 if (BI->isConditional()) 88 return (I == succ_begin(Node)) ? "T" : "F"; 89 90 // Label source of switch edges with the associated value. 91 if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) { 92 unsigned SuccNo = I.getSuccessorIndex(); 93 94 if (SuccNo == 0) return "def"; 95 96 std::string Str; 97 raw_string_ostream OS(Str); 98 OS << SI->getCaseValue(SuccNo)->getValue(); 99 return OS.str(); 100 } 101 return ""; 102 } 103 }; 104 } // End llvm namespace 105 106 namespace llvm { 107 class FunctionPass; 108 FunctionPass *createCFGPrinterPass (); 109 FunctionPass *createCFGOnlyPrinterPass (); 110 } // End llvm namespace 111 112 #endif 113