summaryrefslogtreecommitdiff
path: root/include/llvm/Function.h
blob: 93b9dc6d7abfe5f6e09e0b8c0e5409a3abb598d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
//===-- llvm/Method.h - Class to represent a single VM method ----*- C++ -*--=//
//
// This file contains the declaration of the Method class, which represents a 
// single Method/function/procedure in the VM.
//
// Note that basic blocks themselves are Def's, because they are referenced
// by instructions like calls and can go in virtual function tables and stuff.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_METHOD_H
#define LLVM_METHOD_H

#include "llvm/SymTabValue.h"
#include "llvm/BasicBlock.h"
#include "llvm/GlobalValue.h"

class Instruction;
class BasicBlock;
class MethodArgument;
class MethodType;
class Module;

class Method : public GlobalValue, public SymTabValue {
public:
  typedef ValueHolder<MethodArgument, Method, Method> ArgumentListType;
  typedef ValueHolder<BasicBlock    , Method, Method> BasicBlocksType;

  // BasicBlock iterators...
  typedef BasicBlocksType::iterator iterator;
  typedef BasicBlocksType::const_iterator const_iterator;
  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  typedef std::reverse_iterator<iterator>             reverse_iterator;

private:

  // Important things that make up a method!
  BasicBlocksType  BasicBlocks;         // The basic blocks
  ArgumentListType ArgumentList;        // The formal arguments
  
  friend class ValueHolder<Method, Module, Module>;
  void setParent(Module *parent);

public:
  Method(const MethodType *Ty, bool isInternal, const std::string &Name = "");
  ~Method();

  // Specialize setName to handle symbol table majik...
  virtual void setName(const std::string &name, SymbolTable *ST = 0);

  const Type *getReturnType() const;        // Return the return type of method
  const MethodType *getMethodType() const;  // Return the MethodType for me

  // Is the body of this method unknown? (the basic block list is empty if so)
  // this is true for external methods, defined as forward "declare"ations
  bool isExternal() const { return BasicBlocks.empty(); }

  // Get the underlying elements of the Method... both the argument list and
  // basic block list are empty for external methods.
  //
  inline const ArgumentListType &getArgumentList() const{ return ArgumentList; }
  inline       ArgumentListType &getArgumentList()      { return ArgumentList; }

  inline const BasicBlocksType  &getBasicBlocks() const { return BasicBlocks; }
  inline       BasicBlocksType  &getBasicBlocks()       { return BasicBlocks; }

  inline const BasicBlock       *getEntryNode() const   { return front(); }
  inline       BasicBlock       *getEntryNode()         { return front(); }
  
  //===--------------------------------------------------------------------===//
  // BasicBlock iterator forwarding functions
  //
  inline iterator                begin()       { return BasicBlocks.begin(); }
  inline const_iterator          begin() const { return BasicBlocks.begin(); }
  inline iterator                end  ()       { return BasicBlocks.end();   }
  inline const_iterator          end  () const { return BasicBlocks.end();   }

  inline reverse_iterator       rbegin()       { return BasicBlocks.rbegin(); }
  inline const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
  inline reverse_iterator       rend  ()       { return BasicBlocks.rend();   }
  inline const_reverse_iterator rend  () const { return BasicBlocks.rend();   }

  inline unsigned                 size() const { return BasicBlocks.size(); }
  inline bool                    empty() const { return BasicBlocks.empty(); }
  inline const BasicBlock       *front() const { return BasicBlocks.front(); }
  inline       BasicBlock       *front()       { return BasicBlocks.front(); }
  inline const BasicBlock        *back() const { return BasicBlocks.back(); }
  inline       BasicBlock        *back()       { return BasicBlocks.back(); }


  // Methods for support type inquiry through isa, cast, and dyn_cast:
  static inline bool classof(const Method *T) { return true; }
  static inline bool classof(const Value *V) {
    return V->getValueType() == Value::MethodVal;
  }

  // dropAllReferences() - This function causes all the subinstructions to "let
  // go" of all references that they are maintaining.  This allows one to
  // 'delete' a whole class at a time, even though there may be circular
  // references... first all references are dropped, and all use counts go to
  // zero.  Then everything is delete'd for real.  Note that no operations are
  // valid on an object that has "dropped all references", except operator 
  // delete.
  //
  void dropAllReferences();

  //===--------------------------------------------------------------------===//
  // Method Instruction iterator code
  //===--------------------------------------------------------------------===//
  // 
  template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t> 
  class InstIterator;
  typedef InstIterator<BasicBlocksType, iterator, 
		       BasicBlock::iterator, Instruction*> inst_iterator;
  typedef InstIterator<const BasicBlocksType, const_iterator, 
		       BasicBlock::const_iterator,
		       const Instruction*> const_inst_iterator;

  // This inner class is used to implement inst_begin() & inst_end() for
  // inst_iterator and const_inst_iterator's.
  //
  template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
  class InstIterator {
    typedef _BB_t   BBty;
    typedef _BB_i_t BBIty;
    typedef _BI_t   BIty;
    typedef _II_t   IIty;
    _BB_t  &BBs;      // BasicBlocksType
    _BB_i_t BB;       // BasicBlocksType::iterator
    _BI_t   BI;       // BasicBlock::iterator
  public:
    typedef std::bidirectional_iterator_tag iterator_category;
    typedef IIty                            value_type;
    typedef unsigned                        difference_type;
    typedef BIty                            pointer;
    typedef IIty                            reference;
    
    template<class M> InstIterator(M &m) 
      : BBs(m.getBasicBlocks()), BB(BBs.begin()) {    // begin ctor
      if (BB != BBs.end()) {
	BI = (*BB)->begin();
	resyncInstructionIterator();
      }
    }

    template<class M> InstIterator(M &m, bool) 
      : BBs(m.getBasicBlocks()), BB(BBs.end()) {    // end ctor
    }

    // Accessors to get at the underlying iterators...
    inline BBIty &getBasicBlockIterator()  { return BB; }
    inline BIty  &getInstructionIterator() { return BI; }

    inline IIty operator*()  const { return *BI; }
    inline IIty operator->() const { return operator*(); }

    inline bool operator==(const InstIterator &y) const { 
      return BB == y.BB && (BB == BBs.end() || BI == y.BI);
    }
    inline bool operator!=(const InstIterator& y) const { 
      return !operator==(y);
    }

    // resyncInstructionIterator - This should be called if the 
    // InstructionIterator is modified outside of our control.  This resynchs
    // the internals of the InstIterator to a consistent state.
    //
    inline void resyncInstructionIterator() {
      // The only way that the II could be broken is if it is now pointing to
      // the end() of the current BasicBlock and there are successor BBs.
      while (BI == (*BB)->end()) {
	++BB;
	if (BB == BBs.end()) break;
	BI = (*BB)->begin();
      }
    }

    InstIterator& operator++() { 
      ++BI;
      resyncInstructionIterator();   // Make sure it is still valid.
      return *this; 
    }
    inline InstIterator operator++(int) { 
      InstIterator tmp = *this; ++*this; return tmp; 
    }
    
    InstIterator& operator--() { 
      while (BB == BBs.end() || BI == (*BB)->begin()) {
	--BB;
	BI = (*BB)->end();
      }
      --BI;
      return *this; 
    }
    inline InstIterator  operator--(int) { 
      InstIterator tmp = *this; --*this; return tmp; 
    }

    inline bool atEnd() const { return BB == BBs.end(); }
  };

  inline inst_iterator inst_begin() { return inst_iterator(*this); }
  inline inst_iterator inst_end()   { return inst_iterator(*this, true); }
  inline const_inst_iterator inst_begin() const { return const_inst_iterator(*this); }
  inline const_inst_iterator inst_end()   const { return const_inst_iterator(*this, true); }
};

// Provide specializations of GraphTraits to be able to treat a method as a 
// graph of basic blocks... these are the same as the basic block iterators,
// except that the root node is implicitly the first node of the method.
//
template <> struct GraphTraits<Method*> : public GraphTraits<BasicBlock*> {
  static NodeType *getEntryNode(Method *M) { return M->front(); }
};
template <> struct GraphTraits<const Method*> :
  public GraphTraits<const BasicBlock*> {
  static NodeType *getEntryNode(const Method *M) { return M->front(); }
};

// Provide specializations of GraphTraits to be able to treat a method as a 
// graph of basic blocks... and to walk it in inverse order.  Inverse order for
// a method is considered to be when traversing the predecessor edges of a BB
// instead of the successor edges.
//
template <> struct GraphTraits<Inverse<Method*> > :
  public GraphTraits<Inverse<BasicBlock*> > {
  static NodeType *getEntryNode(Inverse<Method *> G) { return G.Graph->front();}
};
template <> struct GraphTraits<Inverse<const Method*> > :
  public GraphTraits<Inverse<const BasicBlock*> > {
  static NodeType *getEntryNode(Inverse<const Method *> G) {
    return G.Graph->front();
  }
};

#endif