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