CFG.h: change the iterator tag
[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   typedef BasicBlocksType::iterator iterator;
32 private:
33
34   // Important things that make up a method!
35   BasicBlocksType  BasicBlocks;    // The basic blocks
36   ArgumentListType ArgumentList;   // The formal arguments
37
38   Module *Parent;                  // The module that contains this method
39
40   friend class ValueHolder<Method,Module>;
41   void setParent(Module *parent);
42
43 public:
44   Method(const MethodType *Ty, const string &Name = "");
45   ~Method();
46
47   // Specialize setName to handle symbol table majik...
48   virtual void setName(const string &name);
49
50   const Type *getReturnType() const;
51   const MethodType *getMethodType() const;
52
53   // Is the body of this method unknown? (the basic block list is empty if so)
54   // this is true for "extern"al methods.
55   bool isMethodExternal() const { return BasicBlocks.empty(); }
56
57
58   // Get the class structure that this method is contained inside of...
59   inline Module *getParent() { return Parent; }
60   inline const Module *getParent() const { return Parent; }
61
62   inline const BasicBlocksType  &getBasicBlocks() const { return BasicBlocks; }
63   inline       BasicBlocksType  &getBasicBlocks()       { return BasicBlocks; }
64
65   inline const ArgumentListType &getArgumentList() const{ return ArgumentList; }
66   inline       ArgumentListType &getArgumentList()      { return ArgumentList; }
67
68
69   // dropAllReferences() - This function causes all the subinstructions to "let
70   // go" of all references that they are maintaining.  This allows one to
71   // 'delete' a whole class at a time, even though there may be circular
72   // references... first all references are dropped, and all use counts go to
73   // zero.  Then everything is delete'd for real.  Note that no operations are
74   // valid on an object that has "dropped all references", except operator 
75   // delete.
76   //
77   void dropAllReferences();
78
79   //===--------------------------------------------------------------------===//
80   // Method Instruction iterator code
81   //===--------------------------------------------------------------------===//
82   // 
83   template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t> 
84   class InstIterator;
85   typedef InstIterator<BasicBlocksType, BasicBlocksType::iterator, 
86                        BasicBlock::InstListType::iterator,
87                        Instruction*> inst_iterator;
88   typedef InstIterator<const BasicBlocksType, BasicBlocksType::const_iterator, 
89                        BasicBlock::InstListType::const_iterator,
90                        const Instruction*> inst_const_iterator;
91
92   // This inner class is used to implement inst_begin() & inst_end() for
93   // inst_iterator and inst_const_iterator's.
94   //
95   template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
96   class InstIterator {
97     typedef _BB_t   BBty;
98     typedef _BB_i_t BBIty;
99     typedef _BI_t   BIty;
100     typedef _II_t   IIty;
101     _BB_t  &BBs;      // BasicBlocksType
102     _BB_i_t BB;       // BasicBlocksType::iterator
103     _BI_t   BI;       // BasicBlock::InstListType::iterator
104   public:
105     typedef bidirectional_iterator_tag iterator_category;
106
107     template<class M> InstIterator(M &m) 
108       : BBs(m.getBasicBlocks()), BB(BBs.begin()) {    // begin ctor
109       if (BB != BBs.end()) {
110         BI = (*BB)->getInstList().begin();
111         resyncInstructionIterator();
112       }
113     }
114
115     template<class M> InstIterator(M &m, bool) 
116       : BBs(m.getBasicBlocks()), BB(BBs.end()) {    // end ctor
117     }
118
119     // Accessors to get at the underlying iterators...
120     inline BBIty &getBasicBlockIterator()  { return BB; }
121     inline BIty  &getInstructionIterator() { return BI; }
122
123     inline IIty operator*()  const { return *BI; }
124     inline IIty *operator->() const { return &(operator*()); }
125
126     inline bool operator==(const InstIterator &y) const { 
127       return BB == y.BB && (BI == y.BI || BB == BBs.end());
128     }
129     inline bool operator!=(const InstIterator& y) const { 
130       return !operator==(y);
131     }
132
133     // resyncInstructionIterator - This should be called if the 
134     // InstructionIterator is modified outside of our control.  This resynchs
135     // the internals of the InstIterator to a consistent state.
136     //
137     inline void resyncInstructionIterator() {
138       // The only way that the II could be broken is if it is now pointing to
139       // the end() of the current BasicBlock and there are successor BBs.
140       while (BI == (*BB)->getInstList().end()) {
141         ++BB; 
142         if (BB == BBs.end()) break;
143         BI = (*BB)->getInstList().begin();
144       }
145     }
146
147     InstIterator& operator++() { 
148       ++BI;
149       resyncInstructionIterator();   // Make sure it is still valid.
150       return *this; 
151     }
152     inline InstIterator operator++(int) { 
153       InstIterator tmp = *this; ++*this; return tmp; 
154     }
155     
156     InstIterator& operator--() { 
157       while (BB == BBs.end() || BI == (*BB)->getInstList().begin()) {
158         --BB;
159         BI = (*BB)->getInstList().end();
160       }
161       --BI;
162       return *this; 
163     }
164     inline InstIterator  operator--(int) { 
165       InstIterator tmp = *this; --*this; return tmp; 
166     }
167   };
168
169   inline inst_iterator inst_begin() { return inst_iterator(*this); }
170   inline inst_iterator inst_end()   { return inst_iterator(*this, true); }
171   inline inst_const_iterator inst_begin() const { return inst_const_iterator(*this); }
172   inline inst_const_iterator inst_end()   const { return inst_const_iterator(*this, true); }
173 };
174
175 #endif