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