* Minor cleanups
[oota-llvm.git] / include / llvm / Function.h
index 7eb526f6a22ece5b591cdf71a70337664733b9db..93b9dc6d7abfe5f6e09e0b8c0e5409a3abb598d1 100644 (file)
 
 #include "llvm/SymTabValue.h"
 #include "llvm/BasicBlock.h"
-#include <list>
+#include "llvm/GlobalValue.h"
 
 class Instruction;
 class BasicBlock;
 class MethodArgument;
 class MethodType;
-class Method;
 class Module;
 
-typedef UseTy<Method> MethodUse;
-
-class Method : public SymTabValue {
+class Method : public GlobalValue, public SymTabValue {
 public:
-  typedef ValueHolder<MethodArgument, Method> ArgumentListType;
-  typedef ValueHolder<BasicBlock    , Method> BasicBlocksType;
+  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
-
-  Module *Parent;                  // The module that contains this method
-
-  friend class ValueHolder<Method,Module>;
+  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, const string &Name = "");
+  Method(const MethodType *Ty, bool isInternal, const std::string &Name = "");
   ~Method();
 
   // Specialize setName to handle symbol table majik...
-  virtual void setName(const string &name);
+  virtual void setName(const std::string &name, SymbolTable *ST = 0);
 
-  const Type *getReturnType() const;
-  const MethodType *getMethodType() const;
+  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 "extern"al methods.
-  bool isMethodExternal() const { return BasicBlocks.empty(); }
-
+  // this is true for external methods, defined as forward "declare"ations
+  bool isExternal() const { return BasicBlocks.empty(); }
 
-  // Get the class structure that this method is contained inside of...
-  inline Module *getParent() { return Parent; }
-  inline const Module *getParent() const { return Parent; }
+  // 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 ArgumentListType &getArgumentList() const{ return ArgumentList; }
-  inline       ArgumentListType &getArgumentList()      { return ArgumentList; }
-
+  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
@@ -82,15 +110,14 @@ public:
   // 
   template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t> 
   class InstIterator;
-  typedef InstIterator<BasicBlocksType, BasicBlocksType::iterator, 
-                      BasicBlock::InstListType::iterator,
-                      Instruction*> inst_iterator;
-  typedef InstIterator<const BasicBlocksType, BasicBlocksType::const_iterator, 
-                      BasicBlock::InstListType::const_iterator,
-                      const Instruction*> inst_const_iterator;
+  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 inst_const_iterator's.
+  // inst_iterator and const_inst_iterator's.
   //
   template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
   class InstIterator {
@@ -100,14 +127,18 @@ public:
     typedef _II_t   IIty;
     _BB_t  &BBs;      // BasicBlocksType
     _BB_i_t BB;       // BasicBlocksType::iterator
-    _BI_t   BI;       // BasicBlock::InstListType::iterator
+    _BI_t   BI;       // BasicBlock::iterator
   public:
-    typedef bidirectional_iterator_tag iterator_category;
-
+    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)->getInstList().begin();
+       BI = (*BB)->begin();
        resyncInstructionIterator();
       }
     }
@@ -121,10 +152,10 @@ public:
     inline BIty  &getInstructionIterator() { return BI; }
 
     inline IIty operator*()  const { return *BI; }
-    inline IIty *operator->() const { return &(operator*()); }
+    inline IIty operator->() const { return operator*(); }
 
     inline bool operator==(const InstIterator &y) const { 
-      return BB == y.BB && (BI == y.BI || BB == BBs.end());
+      return BB == y.BB && (BB == BBs.end() || BI == y.BI);
     }
     inline bool operator!=(const InstIterator& y) const { 
       return !operator==(y);
@@ -137,10 +168,10 @@ public:
     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)->getInstList().end()) {
-       ++BB; 
+      while (BI == (*BB)->end()) {
+       ++BB;
        if (BB == BBs.end()) break;
-       BI = (*BB)->getInstList().begin();
+       BI = (*BB)->begin();
       }
     }
 
@@ -154,9 +185,9 @@ public:
     }
     
     InstIterator& operator--() { 
-      while (BB == BBs.end() || BI == (*BB)->getInstList().begin()) {
+      while (BB == BBs.end() || BI == (*BB)->begin()) {
        --BB;
-       BI = (*BB)->getInstList().end();
+       BI = (*BB)->end();
       }
       --BI;
       return *this; 
@@ -164,12 +195,42 @@ public:
     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 inst_const_iterator inst_begin() const { return inst_const_iterator(*this); }
-  inline inst_const_iterator inst_end()   const { return inst_const_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