Add extra forwarding accessor methods so that getMethodList(), getBasicBlocks()
[oota-llvm.git] / include / llvm / Function.h
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
18 class Instruction;
19 class BasicBlock;
20 class MethodArgument;
21 class MethodType;
22 class Method;
23 class Module;
24
25 typedef UseTy<Method> MethodUse;
26
27 class Method : public SymTabValue {
28 public:
29   typedef ValueHolder<MethodArgument, Method> ArgumentListType;
30   typedef ValueHolder<BasicBlock    , Method> BasicBlocksType;
31
32   // BasicBlock iterators...
33   typedef BasicBlocksType::iterator iterator;
34   typedef BasicBlocksType::const_iterator const_iterator;
35   typedef reverse_iterator<const_iterator> const_reverse_iterator;
36   typedef reverse_iterator<iterator>             reverse_iterator;
37
38 private:
39
40   // Important things that make up a method!
41   BasicBlocksType  BasicBlocks;    // The basic blocks
42   ArgumentListType ArgumentList;   // The formal arguments
43
44   Module *Parent;                  // The module that contains this method
45
46   friend class ValueHolder<Method,Module>;
47   void setParent(Module *parent);
48
49 public:
50   Method(const MethodType *Ty, const string &Name = "");
51   ~Method();
52
53   // Specialize setName to handle symbol table majik...
54   virtual void setName(const string &name);
55
56   const Type *getReturnType() const;
57   const MethodType *getMethodType() const;
58
59   // Is the body of this method unknown? (the basic block list is empty if so)
60   // this is true for "extern"al methods.
61   bool isMethodExternal() const { return BasicBlocks.empty(); }
62
63
64   // Get the class structure that this method is contained inside of...
65   inline Module *getParent() { return Parent; }
66   inline const Module *getParent() const { return Parent; }
67
68   // Get the underlying elements of the Method...
69   inline const ArgumentListType &getArgumentList() const{ return ArgumentList; }
70   inline       ArgumentListType &getArgumentList()      { return ArgumentList; }
71
72   inline const BasicBlocksType  &getBasicBlocks() const { return BasicBlocks; }
73   inline       BasicBlocksType  &getBasicBlocks()       { return BasicBlocks; }
74
75
76   //===--------------------------------------------------------------------===//
77   // BasicBlock iterator forwarding functions
78   //
79   inline iterator                begin()       { return BasicBlocks.begin(); }
80   inline const_iterator          begin() const { return BasicBlocks.begin(); }
81   inline iterator                end  ()       { return BasicBlocks.end();   }
82   inline const_iterator          end  () const { return BasicBlocks.end();   }
83
84   inline reverse_iterator       rbegin()       { return BasicBlocks.rbegin(); }
85   inline const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
86   inline reverse_iterator       rend  ()       { return BasicBlocks.rend();   }
87   inline const_reverse_iterator rend  () const { return BasicBlocks.rend();   }
88
89   inline unsigned                 size() const { return BasicBlocks.size(); }
90   inline bool                    empty() const { return BasicBlocks.empty(); }
91   inline const BasicBlock       *front() const { return BasicBlocks.front(); }
92   inline       BasicBlock       *front()       { return BasicBlocks.front(); }
93   inline const BasicBlock        *back() const { return BasicBlocks.back(); }
94   inline       BasicBlock        *back()       { return BasicBlocks.back(); }
95
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 && (BI == y.BI || BB == BBs.end());
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
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 #endif