Add a pointer to the owning LLVMContext to Module. This requires threading LLVMConte...
[oota-llvm.git] / lib / Bitcode / Reader / BitcodeReader.h
index e8ad1ddaca7a92bb9909deb47b2cdc6f96cd8995..498a34ae01bf19c92a1ebda920ede321e0998894 100644 (file)
 #include "llvm/OperandTraits.h"
 #include "llvm/Bitcode/BitstreamReader.h"
 #include "llvm/Bitcode/LLVMBitCodes.h"
+#include "llvm/Support/ValueHandle.h"
 #include "llvm/ADT/DenseMap.h"
 #include <vector>
 
 namespace llvm {
   class MemoryBuffer;
+  class LLVMContext;
   
 //===----------------------------------------------------------------------===//
 //                          BitcodeReaderValueList Class
 //===----------------------------------------------------------------------===//
 
-class BitcodeReaderValueList : public User {
-  unsigned Capacity;
+class BitcodeReaderValueList {
+  std::vector<WeakVH> ValuePtrs;
   
   /// ResolveConstants - As we resolve forward-referenced constants, we add
   /// information about them to this vector.  This allows us to resolve them in
@@ -43,91 +45,51 @@ class BitcodeReaderValueList : public User {
   typedef std::vector<std::pair<Constant*, unsigned> > ResolveConstantsTy;
   ResolveConstantsTy ResolveConstants;
 public:
-  BitcodeReaderValueList() : User(Type::VoidTy, Value::ArgumentVal, 0, 0)
-                           , Capacity(0) {}
+  BitcodeReaderValueList() {}
   ~BitcodeReaderValueList() {
     assert(ResolveConstants.empty() && "Constants not resolved?");
   }
 
-  /// Provide fast operand accessors
-  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
-
   // vector compatibility methods
-  unsigned size() const { return getNumOperands(); }
-  void resize(unsigned);
+  unsigned size() const { return ValuePtrs.size(); }
+  void resize(unsigned N) { ValuePtrs.resize(N); }
   void push_back(Value *V) {
-    unsigned OldOps(NumOperands), NewOps(NumOperands + 1);
-    resize(NewOps);
-    NumOperands = NewOps;
-    OperandList[OldOps] = V;
+    ValuePtrs.push_back(V);
   }
   
   void clear() {
     assert(ResolveConstants.empty() && "Constants not resolved?");
-    if (OperandList) dropHungoffUses(OperandList);
-    Capacity = 0;
+    ValuePtrs.clear();
   }
   
-  Value *operator[](unsigned i) const { return getOperand(i); }
+  Value *operator[](unsigned i) const {
+    assert(i < ValuePtrs.size());
+    return ValuePtrs[i];
+  }
   
-  Value *back() const { return getOperand(size() - 1); }
-  void pop_back() { setOperand(size() - 1, 0); --NumOperands; }
-  bool empty() const { return NumOperands == 0; }
+  Value *back() const { return ValuePtrs.back(); }
+    void pop_back() { ValuePtrs.pop_back(); }
+  bool empty() const { return ValuePtrs.empty(); }
   void shrinkTo(unsigned N) {
-    assert(N <= NumOperands && "Invalid shrinkTo request!");
-    while (NumOperands > N)
-      pop_back();
+    assert(N <= size() && "Invalid shrinkTo request!");
+    ValuePtrs.resize(N);
   }
-  virtual void print(std::ostream&) const {}
   
   Constant *getConstantFwdRef(unsigned Idx, const Type *Ty);
   Value *getValueFwdRef(unsigned Idx, const Type *Ty);
   
-  void AssignValue(Value *V, unsigned Idx) {
-    if (Idx == size()) {
-      push_back(V);
-    } else if (Value *OldV = getOperand(Idx)) {
-      // Handle constants and non-constants (e.g. instrs) differently for
-      // efficiency.
-      if (Constant *PHC = dyn_cast<Constant>(OldV)) {
-        ResolveConstants.push_back(std::make_pair(PHC, Idx));
-        setOperand(Idx, V);
-      } else {
-        // If there was a forward reference to this value, replace it.
-        setOperand(Idx, V);
-        OldV->replaceAllUsesWith(V);
-        delete OldV;
-      }
-    } else {
-      initVal(Idx, V);
-    }
-  }
+  void AssignValue(Value *V, unsigned Idx);
   
   /// ResolveConstantForwardRefs - Once all constants are read, this method bulk
   /// resolves any forward references.
   void ResolveConstantForwardRefs();
-  
-private:
-  void initVal(unsigned Idx, Value *V) {
-    if (Idx >= size()) {
-      // Insert a bunch of null values.
-      resize(Idx * 2 + 1);
-    }
-    assert(getOperand(Idx) == 0 && "Cannot init an already init'd Use!");
-    OperandList[Idx] = V;
-  }
 };
 
-template <>
-struct OperandTraits<BitcodeReaderValueList>
-  : HungoffOperandTraits</*16 FIXME*/> {
-};
-
-DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitcodeReaderValueList, Value)  
-
 class BitcodeReader : public ModuleProvider {
+  LLVMContext* Context;
   MemoryBuffer *Buffer;
-  BitstreamReader Stream;
+  BitstreamReader StreamFile;
+  BitstreamCursor Stream;
   
   const char *ErrorString;
   
@@ -136,10 +98,10 @@ class BitcodeReader : public ModuleProvider {
   std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
   std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
   
-  /// Attributes - The set of parameter attributes by index.  Index zero in the
+  /// MAttributes - The set of attributes by index.  Index zero in the
   /// file is for null, and is thus not represented here.  As such all indices
   /// are off by one.
-  std::vector<AttrListPtr> Attributes;
+  std::vector<AttrListPtr> MAttributes;
   
   /// FunctionBBs - While parsing a function body, this is a list of the basic
   /// blocks for the function.
@@ -163,8 +125,8 @@ class BitcodeReader : public ModuleProvider {
   /// stream) and what linkage the original function had.
   DenseMap<Function*, std::pair<uint64_t, unsigned> > DeferredFunctionInfo;
 public:
-  explicit BitcodeReader(MemoryBuffer *buffer)
-      : Buffer(buffer), ErrorString(0) {
+  explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext* C)
+      : Context(C), Buffer(buffer), ErrorString(0) {
     HasReversedFunctionsWithBodies = false;
   }
   ~BitcodeReader() {
@@ -204,8 +166,8 @@ private:
     return FunctionBBs[ID];
   }
   AttrListPtr getAttributes(unsigned i) const {
-    if (i-1 < Attributes.size())
-      return Attributes[i-1];
+    if (i-1 < MAttributes.size())
+      return MAttributes[i-1];
     return AttrListPtr();
   }