Break line to fit 80 columns
[oota-llvm.git] / lib / Bytecode / Reader / ReaderInternals.h
index ec486d851e4065373dfe588cbef931ab8090cc8e..4b1974e01963b4270a33a7724f0975e6b128d2fc 100644 (file)
@@ -8,28 +8,26 @@
 #define READER_INTERNALS_H
 
 #include "llvm/Bytecode/Primitives.h"
-#include "llvm/SymTabValue.h"
-#include "llvm/Method.h"
+#include "llvm/Function.h"
+#include "llvm/BasicBlock.h"
 #include "llvm/Instruction.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Constant.h"
+#include "Support/NonCopyable.h"
 #include <map>
 #include <utility>
 #include <list>
+#include <iostream>
 
 // Enable to trace to figure out what the heck is going on when parsing fails
 #define TRACE_LEVEL 0
 
 #if TRACE_LEVEL    // ByteCodeReading_TRACEer
-#include "llvm/Assembly/Writer.h"
-#define BCR_TRACE(n, X) if (n < TRACE_LEVEL) cerr << string(n*2, ' ') << X
+#define BCR_TRACE(n, X) if (n < TRACE_LEVEL) std::cerr << std::string(n*2, ' ') << X
 #else
 #define BCR_TRACE(n, X)
 #endif
 
-class BasicBlock;
-class Method;
-class Module;
-class Type;
-
 typedef unsigned char uchar;
 
 struct RawInst {       // The raw fields out of the bytecode stream...
@@ -39,11 +37,42 @@ struct RawInst {       // The raw fields out of the bytecode stream...
   unsigned Arg1, Arg2;
   union {
     unsigned Arg3;
-    vector<unsigned> *VarArgs;   // Contains arg #3,4,5... if NumOperands > 3
+    std::vector<unsigned> *VarArgs; // Contains arg #3,4,5... if NumOperands > 3
   };
 };
 
+
+class ConstantFwdRefs: public NonCopyable {
+  Module* TheModule;
+  
+  // GlobalRefs - This maintains a mapping between <Type, Slot #>'s and forward
+  // references to global values or constants.  Such values may be referenced
+  // before they are defined, and if so, the temporary object that they
+  // represent is held here.
+  //
+  typedef std::map<std::pair<const Type *, unsigned>,
+                   Value*>  GlobalRefsType;
+  GlobalRefsType GlobalRefs;
+
+  Value*       find                   (const Type* Ty, unsigned Slot);
+  void         insert                 (const Type* Ty, unsigned Slot, Value* V);
+  void         erase                  (const Type* Ty, unsigned Slot);
+
+public:
+  // sets the current module pointer: needed to insert placeholder globals
+  void         VisitingModule         (Module* M) { TheModule = M; }
+  
+  // get a forward reference to a global or a constant
+  GlobalValue* GetFwdRefToGlobal      (const PointerType* PT, unsigned Slot);
+  Constant*    GetFwdRefToConstant    (const Type* Ty,        unsigned Slot);
+
+  // resolve all references to the placeholder (if any) for the given value
+  void         ResolveRefsToValue     (Value* val, unsigned Slot);
+};
+
+
 class BytecodeParser : public AbstractTypeUser {
+  std::string Error;     // Error message string goes here...
 public:
   BytecodeParser() {
     // Define this in case we don't see a ModuleGlobalInfo block.
@@ -51,16 +80,28 @@ public:
   }
 
   Module *ParseBytecode(const uchar *Buf, const uchar *EndBuf);
+
+  std::string getError() const { return Error; }
+
+  void dump() const {
+    std::cerr << "BytecodeParser instance!\n";
+  }
+
 private:          // All of this data is transient across calls to ParseBytecode
-  typedef vector<Value *> ValueList;
-  typedef vector<ValueList> ValueTable;
+  Module *TheModule;   // Current Module being read into...
+  
+  typedef std::vector<Value *> ValueList;
+  typedef std::vector<ValueList> ValueTable;
   ValueTable Values, LateResolveValues;
   ValueTable ModuleValues, LateResolveModuleValues;
 
+  // fwdRefs - This manages forward references to global values.
+  ConstantFwdRefs fwdRefs;
+
   // TypesLoaded - This vector mirrors the Values[TypeTyID] plane.  It is used
   // to deal with forward references to types.
   //
-  typedef vector<PATypeHandle<Type> > TypeValuesListTy;
+  typedef std::vector<PATypeHandle<Type> > TypeValuesListTy;
   TypeValuesListTy ModuleTypeValues;
   TypeValuesListTy MethodTypeValues;
 
@@ -72,11 +113,11 @@ private:          // All of this data is transient across calls to ParseBytecode
   // into its slot to reserve it.  When the method is loaded, this placeholder
   // is replaced.
   //
-  list<pair<const PointerType *, unsigned> > MethodSignatureList;
+  std::list<std::pair<const PointerType *, unsigned> > MethodSignatureList;
 
 private:
-  bool ParseModule            (const uchar * Buf, const uchar *End, Module *&);
-  bool ParseModuleGlobalInfo  (const uchar *&Buf, const uchar *End, Module *);
+  bool ParseModule          (const uchar * Buf, const uchar *End, Module *&);
+  bool ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End, Module *);
   bool ParseSymbolTable   (const uchar *&Buf, const uchar *End, SymbolTable *);
   bool ParseMethod        (const uchar *&Buf, const uchar *End, Module *);
   bool ParseBasicBlock    (const uchar *&Buf, const uchar *End, BasicBlock *&);
@@ -85,8 +126,8 @@ private:
 
   bool ParseConstantPool(const uchar *&Buf, const uchar *EndBuf,
                         ValueTable &Tab, TypeValuesListTy &TypeTab);
-  bool parseConstPoolValue(const uchar *&Buf, const uchar *End,
-                          const Type *Ty, ConstPoolVal *&V);
+  bool parseConstantValue(const uchar *&Buf, const uchar *End,
+                          const Type *Ty, Constant *&V);
   bool parseTypeConstants(const uchar *&Buf, const uchar *EndBuf,
                          TypeValuesListTy &Tab, unsigned NumEntries);
   const Type *parseTypeConstant(const uchar *&Buf, const uchar *EndBuf);
@@ -94,12 +135,17 @@ private:
   Value      *getValue(const Type *Ty, unsigned num, bool Create = true);
   const Type *getType(unsigned ID);
 
-  bool insertValue(Value *D, vector<ValueList> &D);
+  int insertValue(Value *D, std::vector<ValueList> &D);  // -1 = Failure
   bool postResolveValues(ValueTable &ValTab);
 
   bool getTypeSlot(const Type *Ty, unsigned &Slot);
 
-
+  // resolveRefsToGlobal   -- resolve forward references to a global
+  // resolveRefsToConstant -- resolve forward references to a constant
+  // 
+  void resolveRefsToGlobal(GlobalValue* GV, unsigned Slot);
+  void resolveRefsToConstant(Constant* C, unsigned Slot);
+  
   // refineAbstractType - The callback method is invoked when one of the
   // elements of TypeValues becomes more concrete...
   //
@@ -109,6 +155,7 @@ private:
 template<class SuperType>
 class PlaceholderDef : public SuperType {
   unsigned ID;
+  PlaceholderDef();                     // do not implement
 public:
   PlaceholderDef(const Type *Ty, unsigned id) : SuperType(Ty), ID(id) {}
   unsigned getID() { return ID; }
@@ -123,25 +170,37 @@ struct InstPlaceHolderHelper : public Instruction {
 
 struct BBPlaceHolderHelper : public BasicBlock {
   BBPlaceHolderHelper(const Type *Ty) : BasicBlock() {
-    assert(Ty->isLabelType());
+    assert(Ty == Type::LabelTy);
   }
 };
 
-struct MethPlaceHolderHelper : public Method {
+struct MethPlaceHolderHelper : public Function {
   MethPlaceHolderHelper(const Type *Ty) 
-    : Method(cast<const MethodType>(Ty)) {
+    : Function(cast<const FunctionType>(Ty), true) {
   }
 };
 
+struct ConstantPlaceHolderHelper : public Constant {
+  ConstantPlaceHolderHelper(const Type *Ty)
+    : Constant(Ty) {}
+  virtual bool isNullValue() const { return false; }
+};
+
 typedef PlaceholderDef<InstPlaceHolderHelper>  DefPHolder;
 typedef PlaceholderDef<BBPlaceHolderHelper>    BBPHolder;
 typedef PlaceholderDef<MethPlaceHolderHelper>  MethPHolder;
+typedef PlaceholderDef<ConstantPlaceHolderHelper>  ConstPHolder;
+
 
 static inline unsigned getValueIDNumberFromPlaceHolder(Value *Def) {
+  if (isa<Constant>(Def))
+    return ((ConstPHolder*)Def)->getID();
+  
+  // else discriminate by type
   switch (Def->getType()->getPrimitiveID()) {
-  case Type::LabelTyID:  return ((BBPHolder*)Def)->getID();
-  case Type::MethodTyID: return ((MethPHolder*)Def)->getID();
-  default:               return ((DefPHolder*)Def)->getID();
+  case Type::LabelTyID:    return ((BBPHolder*)Def)->getID();
+  case Type::FunctionTyID: return ((MethPHolder*)Def)->getID();
+  default:                 return ((DefPHolder*)Def)->getID();
   }
 }
 
@@ -149,7 +208,7 @@ static inline bool readBlock(const uchar *&Buf, const uchar *EndBuf,
                             unsigned &Type, unsigned &Size) {
 #if DEBUG_OUTPUT
   bool Result = read(Buf, EndBuf, Type) || read(Buf, EndBuf, Size);
-  cerr << "StartLoc = " << ((unsigned)Buf & 4095)
+  std::cerr << "StartLoc = " << ((unsigned)Buf & 4095)
        << " Type = " << Type << " Size = " << Size << endl;
   return Result;
 #else