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/Assembly/Writer.h" 00019 #include "llvm/IR/Constants.h" 00020 #include "llvm/IR/Function.h" 00021 #include "llvm/IR/Instructions.h" 00022 #include "llvm/Support/CFG.h" 00023 #include "llvm/Support/GraphWriter.h" 00024 00025 namespace llvm { 00026 template<> 00027 struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits { 00028 00029 DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} 00030 00031 static std::string getGraphName(const Function *F) { 00032 return "CFG for '" + F->getName().str() + "' function"; 00033 } 00034 00035 static std::string getSimpleNodeLabel(const BasicBlock *Node, 00036 const Function *) { 00037 if (!Node->getName().empty()) 00038 return Node->getName().str(); 00039 00040 std::string Str; 00041 raw_string_ostream OS(Str); 00042 00043 WriteAsOperand(OS, Node, false); 00044 return OS.str(); 00045 } 00046 00047 static std::string getCompleteNodeLabel(const BasicBlock *Node, 00048 const Function *) { 00049 std::string Str; 00050 raw_string_ostream OS(Str); 00051 00052 if (Node->getName().empty()) { 00053 WriteAsOperand(OS, Node, 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 for (unsigned i = 0; i != OutStr.length(); ++i) 00063 if (OutStr[i] == '\n') { // Left justify 00064 OutStr[i] = '\\'; 00065 OutStr.insert(OutStr.begin()+i+1, 'l'); 00066 } else if (OutStr[i] == ';') { // Delete comments! 00067 unsigned Idx = OutStr.find('\n', i+1); // Find end of line 00068 OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx); 00069 --i; 00070 } 00071 00072 return OutStr; 00073 } 00074 00075 std::string getNodeLabel(const BasicBlock *Node, 00076 const Function *Graph) { 00077 if (isSimple()) 00078 return getSimpleNodeLabel(Node, Graph); 00079 else 00080 return getCompleteNodeLabel(Node, Graph); 00081 } 00082 00083 static std::string getEdgeSourceLabel(const BasicBlock *Node, 00084 succ_const_iterator I) { 00085 // Label source of conditional branches with "T" or "F" 00086 if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator())) 00087 if (BI->isConditional()) 00088 return (I == succ_begin(Node)) ? "T" : "F"; 00089 00090 // Label source of switch edges with the associated value. 00091 if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) { 00092 unsigned SuccNo = I.getSuccessorIndex(); 00093 00094 if (SuccNo == 0) return "def"; 00095 00096 std::string Str; 00097 raw_string_ostream OS(Str); 00098 SwitchInst::ConstCaseIt Case = 00099 SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo); 00100 OS << Case.getCaseValue()->getValue(); 00101 return OS.str(); 00102 } 00103 return ""; 00104 } 00105 }; 00106 } // End llvm namespace 00107 00108 namespace llvm { 00109 class FunctionPass; 00110 FunctionPass *createCFGPrinterPass (); 00111 FunctionPass *createCFGOnlyPrinterPass (); 00112 } // End llvm namespace 00113 00114 #endif