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