a7075af0cc33a15a7b3bdbd9edd130cec3f094cf
[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
17 class Instruction;
18 class BasicBlock;
19 class MethodArgument;
20 class MethodType;
21 class Module;
22
23 class Method : public Value, public SymTabValue {
24 public:
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
34 private:
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
45 public:
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 //
207 template <> struct GraphTraits<Method*> : public GraphTraits<BasicBlock*> {
208   static NodeType *getEntryNode(Method *M) { return M->front(); }
209 };
210 template <> 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 //
220 template <> struct GraphTraits<Inverse<Method*> > :
221   public GraphTraits<Inverse<BasicBlock*> > {
222   static NodeType *getEntryNode(Inverse<Method *> G) { return G.Graph->front();}
223 };
224 template <> 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