LLVM API Documentation

CFGPrinter.h
Go to the documentation of this file.
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