Function.h revision f7bd6392906a8edb31a802c835b074e5cbdce774
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 <list>
17
18class Instruction;
19class BasicBlock;
20class MethodArgument;
21class MethodType;
22class Module;
23
24class Method : public Value, 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 reverse_iterator<const_iterator> const_reverse_iterator;
33  typedef 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  Module *Parent;                  // The module that contains this method
42
43  friend class ValueHolder<Method,Module, Module>;
44  void setParent(Module *parent);
45
46public:
47  Method(const MethodType *Ty, const string &Name = "");
48  ~Method();
49
50  // Specialize setName to handle symbol table majik...
51  virtual void setName(const string &name, SymbolTable *ST = 0);
52
53  const Type *getReturnType() const;
54  const MethodType *getMethodType() const;
55
56  // Is the body of this method unknown? (the basic block list is empty if so)
57  // this is true for external methods, defined as forward "declare"ations
58  bool isExternal() const { return BasicBlocks.empty(); }
59
60
61  // Get the class structure that this method is contained inside of...
62  inline Module *getParent() { return Parent; }
63  inline const Module *getParent() const { return Parent; }
64
65  // Get the underlying elements of the Method...
66  inline const ArgumentListType &getArgumentList() const{ return ArgumentList; }
67  inline       ArgumentListType &getArgumentList()      { return ArgumentList; }
68
69  inline const BasicBlocksType  &getBasicBlocks() const { return BasicBlocks; }
70  inline       BasicBlocksType  &getBasicBlocks()       { return BasicBlocks; }
71
72
73  //===--------------------------------------------------------------------===//
74  // BasicBlock iterator forwarding functions
75  //
76  inline iterator                begin()       { return BasicBlocks.begin(); }
77  inline const_iterator          begin() const { return BasicBlocks.begin(); }
78  inline iterator                end  ()       { return BasicBlocks.end();   }
79  inline const_iterator          end  () const { return BasicBlocks.end();   }
80
81  inline reverse_iterator       rbegin()       { return BasicBlocks.rbegin(); }
82  inline const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
83  inline reverse_iterator       rend  ()       { return BasicBlocks.rend();   }
84  inline const_reverse_iterator rend  () const { return BasicBlocks.rend();   }
85
86  inline unsigned                 size() const { return BasicBlocks.size(); }
87  inline bool                    empty() const { return BasicBlocks.empty(); }
88  inline const BasicBlock       *front() const { return BasicBlocks.front(); }
89  inline       BasicBlock       *front()       { return BasicBlocks.front(); }
90  inline const BasicBlock        *back() const { return BasicBlocks.back(); }
91  inline       BasicBlock        *back()       { return BasicBlocks.back(); }
92
93
94
95  // dropAllReferences() - This function causes all the subinstructions to "let
96  // go" of all references that they are maintaining.  This allows one to
97  // 'delete' a whole class at a time, even though there may be circular
98  // references... first all references are dropped, and all use counts go to
99  // zero.  Then everything is delete'd for real.  Note that no operations are
100  // valid on an object that has "dropped all references", except operator
101  // delete.
102  //
103  void dropAllReferences();
104
105  //===--------------------------------------------------------------------===//
106  // Method Instruction iterator code
107  //===--------------------------------------------------------------------===//
108  //
109  template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
110  class InstIterator;
111  typedef InstIterator<BasicBlocksType, iterator,
112		       BasicBlock::iterator, Instruction*> inst_iterator;
113  typedef InstIterator<const BasicBlocksType, const_iterator,
114		       BasicBlock::const_iterator,
115		       const Instruction*> inst_const_iterator;
116
117  // This inner class is used to implement inst_begin() & inst_end() for
118  // inst_iterator and inst_const_iterator's.
119  //
120  template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
121  class InstIterator {
122    typedef _BB_t   BBty;
123    typedef _BB_i_t BBIty;
124    typedef _BI_t   BIty;
125    typedef _II_t   IIty;
126    _BB_t  &BBs;      // BasicBlocksType
127    _BB_i_t BB;       // BasicBlocksType::iterator
128    _BI_t   BI;       // BasicBlock::iterator
129  public:
130    typedef bidirectional_iterator_tag iterator_category;
131
132    template<class M> InstIterator(M &m)
133      : BBs(m.getBasicBlocks()), BB(BBs.begin()) {    // begin ctor
134      if (BB != BBs.end()) {
135	BI = (*BB)->begin();
136	resyncInstructionIterator();
137      }
138    }
139
140    template<class M> InstIterator(M &m, bool)
141      : BBs(m.getBasicBlocks()), BB(BBs.end()) {    // end ctor
142    }
143
144    // Accessors to get at the underlying iterators...
145    inline BBIty &getBasicBlockIterator()  { return BB; }
146    inline BIty  &getInstructionIterator() { return BI; }
147
148    inline IIty operator*()  const { return *BI; }
149    inline IIty operator->() const { return operator*(); }
150
151    inline bool operator==(const InstIterator &y) const {
152      return BB == y.BB && (BI == y.BI || BB == BBs.end());
153    }
154    inline bool operator!=(const InstIterator& y) const {
155      return !operator==(y);
156    }
157
158    // resyncInstructionIterator - This should be called if the
159    // InstructionIterator is modified outside of our control.  This resynchs
160    // the internals of the InstIterator to a consistent state.
161    //
162    inline void resyncInstructionIterator() {
163      // The only way that the II could be broken is if it is now pointing to
164      // the end() of the current BasicBlock and there are successor BBs.
165      while (BI == (*BB)->end()) {
166	++BB;
167	if (BB == BBs.end()) break;
168	BI = (*BB)->begin();
169      }
170    }
171
172    InstIterator& operator++() {
173      ++BI;
174      resyncInstructionIterator();   // Make sure it is still valid.
175      return *this;
176    }
177    inline InstIterator operator++(int) {
178      InstIterator tmp = *this; ++*this; return tmp;
179    }
180
181    InstIterator& operator--() {
182      while (BB == BBs.end() || BI == (*BB)->begin()) {
183	--BB;
184	BI = (*BB)->end();
185      }
186      --BI;
187      return *this;
188    }
189    inline InstIterator  operator--(int) {
190      InstIterator tmp = *this; --*this; return tmp;
191    }
192
193    inline bool atEnd() const { return BB == BBs.end(); }
194  };
195
196  inline inst_iterator inst_begin() { return inst_iterator(*this); }
197  inline inst_iterator inst_end()   { return inst_iterator(*this, true); }
198  inline inst_const_iterator inst_begin() const { return inst_const_iterator(*this); }
199  inline inst_const_iterator inst_end()   const { return inst_const_iterator(*this, true); }
200};
201
202#endif
203