Function.h revision 3ff4387113d7e74a8aa73f80c3518cb95f09a64b
1//===-- llvm/Method.h - Class to represent a single VM method ----*- C++ -*--=// 2// 3// This file contains the declaration of the Method class, which represents a 4// single Method/function/procedure in the VM. 5// 6// Note that basic blocks themselves are Def's, because they are referenced 7// by instructions like calls and can go in virtual function tables and stuff. 8// 9//===----------------------------------------------------------------------===// 10 11#ifndef LLVM_METHOD_H 12#define LLVM_METHOD_H 13 14#include "llvm/SymTabValue.h" 15#include "llvm/BasicBlock.h" 16 17class Instruction; 18class BasicBlock; 19class MethodArgument; 20class MethodType; 21class Module; 22 23class Method : public Value, public SymTabValue { 24public: 25 typedef ValueHolder<MethodArgument, Method, Method> ArgumentListType; 26 typedef ValueHolder<BasicBlock , Method, Method> BasicBlocksType; 27 28 // BasicBlock iterators... 29 typedef BasicBlocksType::iterator iterator; 30 typedef BasicBlocksType::const_iterator const_iterator; 31 typedef reverse_iterator<const_iterator> const_reverse_iterator; 32 typedef reverse_iterator<iterator> reverse_iterator; 33 34private: 35 36 // Important things that make up a method! 37 BasicBlocksType BasicBlocks; // The basic blocks 38 ArgumentListType ArgumentList; // The formal arguments 39 40 Module *Parent; // The module that contains this method 41 42 friend class ValueHolder<Method, Module, Module>; 43 void setParent(Module *parent); 44 45public: 46 Method(const MethodType *Ty, const string &Name = ""); 47 ~Method(); 48 49 // Specialize setName to handle symbol table majik... 50 virtual void setName(const string &name, SymbolTable *ST = 0); 51 52 const Type *getReturnType() const; 53 const MethodType *getType() const { 54 return (const MethodType*)Value::getType(); 55 } 56 57 // Is the body of this method unknown? (the basic block list is empty if so) 58 // this is true for external methods, defined as forward "declare"ations 59 bool isExternal() const { return BasicBlocks.empty(); } 60 61 62 // Get the class structure that this method is contained inside of... 63 inline Module *getParent() { return Parent; } 64 inline const Module *getParent() const { return Parent; } 65 66 // Get the underlying elements of the Method... 67 inline const ArgumentListType &getArgumentList() const{ return ArgumentList; } 68 inline ArgumentListType &getArgumentList() { return ArgumentList; } 69 70 inline const BasicBlocksType &getBasicBlocks() const { return BasicBlocks; } 71 inline BasicBlocksType &getBasicBlocks() { return BasicBlocks; } 72 73 74 //===--------------------------------------------------------------------===// 75 // BasicBlock iterator forwarding functions 76 // 77 inline iterator begin() { return BasicBlocks.begin(); } 78 inline const_iterator begin() const { return BasicBlocks.begin(); } 79 inline iterator end () { return BasicBlocks.end(); } 80 inline const_iterator end () const { return BasicBlocks.end(); } 81 82 inline reverse_iterator rbegin() { return BasicBlocks.rbegin(); } 83 inline const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); } 84 inline reverse_iterator rend () { return BasicBlocks.rend(); } 85 inline const_reverse_iterator rend () const { return BasicBlocks.rend(); } 86 87 inline unsigned size() const { return BasicBlocks.size(); } 88 inline bool empty() const { return BasicBlocks.empty(); } 89 inline const BasicBlock *front() const { return BasicBlocks.front(); } 90 inline BasicBlock *front() { return BasicBlocks.front(); } 91 inline const BasicBlock *back() const { return BasicBlocks.back(); } 92 inline BasicBlock *back() { return BasicBlocks.back(); } 93 94 95 96 // dropAllReferences() - This function causes all the subinstructions to "let 97 // go" of all references that they are maintaining. This allows one to 98 // 'delete' a whole class at a time, even though there may be circular 99 // references... first all references are dropped, and all use counts go to 100 // zero. Then everything is delete'd for real. Note that no operations are 101 // valid on an object that has "dropped all references", except operator 102 // delete. 103 // 104 void dropAllReferences(); 105 106 //===--------------------------------------------------------------------===// 107 // Method Instruction iterator code 108 //===--------------------------------------------------------------------===// 109 // 110 template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t> 111 class InstIterator; 112 typedef InstIterator<BasicBlocksType, iterator, 113 BasicBlock::iterator, Instruction*> inst_iterator; 114 typedef InstIterator<const BasicBlocksType, const_iterator, 115 BasicBlock::const_iterator, 116 const Instruction*> inst_const_iterator; 117 118 // This inner class is used to implement inst_begin() & inst_end() for 119 // inst_iterator and inst_const_iterator's. 120 // 121 template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t> 122 class InstIterator { 123 typedef _BB_t BBty; 124 typedef _BB_i_t BBIty; 125 typedef _BI_t BIty; 126 typedef _II_t IIty; 127 _BB_t &BBs; // BasicBlocksType 128 _BB_i_t BB; // BasicBlocksType::iterator 129 _BI_t BI; // BasicBlock::iterator 130 public: 131 typedef bidirectional_iterator_tag iterator_category; 132 133 template<class M> InstIterator(M &m) 134 : BBs(m.getBasicBlocks()), BB(BBs.begin()) { // begin ctor 135 if (BB != BBs.end()) { 136 BI = (*BB)->begin(); 137 resyncInstructionIterator(); 138 } 139 } 140 141 template<class M> InstIterator(M &m, bool) 142 : BBs(m.getBasicBlocks()), BB(BBs.end()) { // end ctor 143 } 144 145 // Accessors to get at the underlying iterators... 146 inline BBIty &getBasicBlockIterator() { return BB; } 147 inline BIty &getInstructionIterator() { return BI; } 148 149 inline IIty operator*() const { return *BI; } 150 inline IIty operator->() const { return operator*(); } 151 152 inline bool operator==(const InstIterator &y) const { 153 return BB == y.BB && (BI == y.BI || BB == BBs.end()); 154 } 155 inline bool operator!=(const InstIterator& y) const { 156 return !operator==(y); 157 } 158 159 // resyncInstructionIterator - This should be called if the 160 // InstructionIterator is modified outside of our control. This resynchs 161 // the internals of the InstIterator to a consistent state. 162 // 163 inline void resyncInstructionIterator() { 164 // The only way that the II could be broken is if it is now pointing to 165 // the end() of the current BasicBlock and there are successor BBs. 166 while (BI == (*BB)->end()) { 167 ++BB; 168 if (BB == BBs.end()) break; 169 BI = (*BB)->begin(); 170 } 171 } 172 173 InstIterator& operator++() { 174 ++BI; 175 resyncInstructionIterator(); // Make sure it is still valid. 176 return *this; 177 } 178 inline InstIterator operator++(int) { 179 InstIterator tmp = *this; ++*this; return tmp; 180 } 181 182 InstIterator& operator--() { 183 while (BB == BBs.end() || BI == (*BB)->begin()) { 184 --BB; 185 BI = (*BB)->end(); 186 } 187 --BI; 188 return *this; 189 } 190 inline InstIterator operator--(int) { 191 InstIterator tmp = *this; --*this; return tmp; 192 } 193 194 inline bool atEnd() const { return BB == BBs.end(); } 195 }; 196 197 inline inst_iterator inst_begin() { return inst_iterator(*this); } 198 inline inst_iterator inst_end() { return inst_iterator(*this, true); } 199 inline inst_const_iterator inst_begin() const { return inst_const_iterator(*this); } 200 inline inst_const_iterator inst_end() const { return inst_const_iterator(*this, true); } 201}; 202 203// Provide specializations of GraphTraits to be able to treat a method as a 204// graph of basic blocks... these are the same as the basic block iterators, 205// except that the root node is implicitly the first node of the method. 206// 207template <> struct GraphTraits<Method*> : public GraphTraits<BasicBlock*> { 208 static NodeType *getEntryNode(Method *M) { return M->front(); } 209}; 210template <> struct GraphTraits<const Method*> : 211 public GraphTraits<const BasicBlock*> { 212 static NodeType *getEntryNode(const Method *M) { return M->front(); } 213}; 214 215// Provide specializations of GraphTraits to be able to treat a method as a 216// graph of basic blocks... and to walk it in inverse order. Inverse order for 217// a method is considered to be when traversing the predecessor edges of a BB 218// instead of the successor edges. 219// 220template <> struct GraphTraits<Inverse<Method*> > : 221 public GraphTraits<Inverse<BasicBlock*> > { 222 static NodeType *getEntryNode(Inverse<Method *> G) { return G.Graph->front();} 223}; 224template <> struct GraphTraits<Inverse<const Method*> > : 225 public GraphTraits<Inverse<const BasicBlock*> > { 226 static NodeType *getEntryNode(Inverse<const Method *> G) { 227 return G.Graph->front(); 228 } 229}; 230 231#endif 232