LLVM API Documentation
00001 //===-- CFGPrinter.h - CFG printer external interface -----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines external functions that can be called to explicitly 00011 // instantiate the CFG printer. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_ANALYSIS_CFGPRINTER_H 00016 #define LLVM_ANALYSIS_CFGPRINTER_H 00017 00018 #include "llvm/IR/CFG.h" 00019 #include "llvm/IR/Constants.h" 00020 #include "llvm/IR/Function.h" 00021 #include "llvm/IR/Instructions.h" 00022 #include "llvm/Support/GraphWriter.h" 00023 00024 namespace llvm { 00025 template<> 00026 struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits { 00027 00028 DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} 00029 00030 static std::string getGraphName(const Function *F) { 00031 return "CFG for '" + F->getName().str() + "' function"; 00032 } 00033 00034 static std::string getSimpleNodeLabel(const BasicBlock *Node, 00035 const Function *) { 00036 if (!Node->getName().empty()) 00037 return Node->getName().str(); 00038 00039 std::string Str; 00040 raw_string_ostream OS(Str); 00041 00042 Node->printAsOperand(OS, false); 00043 return OS.str(); 00044 } 00045 00046 static std::string getCompleteNodeLabel(const BasicBlock *Node, 00047 const Function *) { 00048 enum { MaxColumns = 80 }; 00049 std::string Str; 00050 raw_string_ostream OS(Str); 00051 00052 if (Node->getName().empty()) { 00053 Node->printAsOperand(OS, false); 00054 OS << ":"; 00055 } 00056 00057 OS << *Node; 00058 std::string OutStr = OS.str(); 00059 if (OutStr[0] == '\n') OutStr.erase(OutStr.begin()); 00060 00061 // Process string output to make it nicer... 00062 unsigned ColNum = 0; 00063 unsigned LastSpace = 0; 00064 for (unsigned i = 0; i != OutStr.length(); ++i) { 00065 if (OutStr[i] == '\n') { // Left justify 00066 OutStr[i] = '\\'; 00067 OutStr.insert(OutStr.begin()+i+1, 'l'); 00068 ColNum = 0; 00069 LastSpace = 0; 00070 } else if (OutStr[i] == ';') { // Delete comments! 00071 unsigned Idx = OutStr.find('\n', i+1); // Find end of line 00072 OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx); 00073 --i; 00074 } else if (ColNum == MaxColumns) { // Wrap lines. 00075 // Wrap very long names even though we can't find a space. 00076 if (!LastSpace) 00077 LastSpace = i; 00078 OutStr.insert(LastSpace, "\\l..."); 00079 ColNum = i - LastSpace; 00080 LastSpace = 0; 00081 i += 3; // The loop will advance 'i' again. 00082 } 00083 else 00084 ++ColNum; 00085 if (OutStr[i] == ' ') 00086 LastSpace = i; 00087 } 00088 return OutStr; 00089 } 00090 00091 std::string getNodeLabel(const BasicBlock *Node, 00092 const Function *Graph) { 00093 if (isSimple()) 00094 return getSimpleNodeLabel(Node, Graph); 00095 else 00096 return getCompleteNodeLabel(Node, Graph); 00097 } 00098 00099 static std::string getEdgeSourceLabel(const BasicBlock *Node, 00100 succ_const_iterator I) { 00101 // Label source of conditional branches with "T" or "F" 00102 if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator())) 00103 if (BI->isConditional()) 00104 return (I == succ_begin(Node)) ? "T" : "F"; 00105 00106 // Label source of switch edges with the associated value. 00107 if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) { 00108 unsigned SuccNo = I.getSuccessorIndex(); 00109 00110 if (SuccNo == 0) return "def"; 00111 00112 std::string Str; 00113 raw_string_ostream OS(Str); 00114 SwitchInst::ConstCaseIt Case = 00115 SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo); 00116 OS << Case.getCaseValue()->getValue(); 00117 return OS.str(); 00118 } 00119 return ""; 00120 } 00121 }; 00122 } // End llvm namespace 00123 00124 namespace llvm { 00125 class FunctionPass; 00126 FunctionPass *createCFGPrinterPass (); 00127 FunctionPass *createCFGOnlyPrinterPass (); 00128 } // End llvm namespace 00129 00130 #endif