00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef LLVM_ANALYSIS_CFGPRINTER_H
00016 #define LLVM_ANALYSIS_CFGPRINTER_H
00017
00018 #include "llvm/Function.h"
00019 #include "llvm/Instructions.h"
00020 #include "llvm/Assembly/Writer.h"
00021 #include "llvm/Support/CFG.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->getNameStr() + "' function";
00032 }
00033
00034 static std::string getSimpleNodeLabel(const BasicBlock *Node,
00035 const Function *Graph) {
00036 if (!Node->getName().empty())
00037 return Node->getNameStr();
00038
00039 std::string Str;
00040 raw_string_ostream OS(Str);
00041
00042 WriteAsOperand(OS, Node, false);
00043 return OS.str();
00044 }
00045
00046 static std::string getCompleteNodeLabel(const BasicBlock *Node,
00047 const Function *Graph) {
00048 std::string Str;
00049 raw_string_ostream OS(Str);
00050
00051 if (Node->getName().empty()) {
00052 WriteAsOperand(OS, Node, false);
00053 OS << ":";
00054 }
00055
00056 OS << *Node;
00057 std::string OutStr = OS.str();
00058 if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
00059
00060
00061 for (unsigned i = 0; i != OutStr.length(); ++i)
00062 if (OutStr[i] == '\n') {
00063 OutStr[i] = '\\';
00064 OutStr.insert(OutStr.begin()+i+1, 'l');
00065 } else if (OutStr[i] == ';') {
00066 unsigned Idx = OutStr.find('\n', i+1);
00067 OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx);
00068 --i;
00069 }
00070
00071 return OutStr;
00072 }
00073
00074 std::string getNodeLabel(const BasicBlock *Node,
00075 const Function *Graph) {
00076 if (isSimple())
00077 return getSimpleNodeLabel(Node, Graph);
00078 else
00079 return getCompleteNodeLabel(Node, Graph);
00080 }
00081
00082 static std::string getEdgeSourceLabel(const BasicBlock *Node,
00083 succ_const_iterator I) {
00084
00085 if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
00086 if (BI->isConditional())
00087 return (I == succ_begin(Node)) ? "T" : "F";
00088
00089
00090 if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
00091 unsigned SuccNo = I.getSuccessorIndex();
00092
00093 if (SuccNo == 0) return "def";
00094
00095 std::string Str;
00096 raw_string_ostream OS(Str);
00097 OS << SI->getCaseValue(SuccNo)->getValue();
00098 return OS.str();
00099 }
00100 return "";
00101 }
00102 };
00103 }
00104
00105 namespace llvm {
00106 class FunctionPass;
00107 FunctionPass *createCFGPrinterPass ();
00108 FunctionPass *createCFGOnlyPrinterPass ();
00109 }
00110
00111 #endif