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