Initial revision


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Bytecode/Reader/ConstantReader.cpp b/lib/Bytecode/Reader/ConstantReader.cpp
new file mode 100644
index 0000000..b85bd88
--- /dev/null
+++ b/lib/Bytecode/Reader/ConstantReader.cpp
@@ -0,0 +1,218 @@
+//===- ReadConst.cpp - Code to constants and constant pools -----------------===
+//
+// This file implements functionality to deserialize constants and entire 
+// constant pools.
+// 
+// Note that this library should be as fast as possible, reentrant, and 
+// threadsafe!!
+//
+//===------------------------------------------------------------------------===
+
+#include "llvm/Module.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/ConstPoolVals.h"
+#include "llvm/DerivedTypes.h"
+#include "ReaderInternals.h"
+
+bool BytecodeParser::parseTypeConstant(const uchar *&Buf, const uchar *EndBuf,
+				       ConstPoolVal *&V) {
+  const Type *Val = 0;
+
+  unsigned PrimType;
+  if (read_vbr(Buf, EndBuf, PrimType)) return true;
+
+  if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType))) {
+    V = new ConstPoolType(Val);    // It's just a primitive ID.
+    return false;
+  }
+  
+  switch (PrimType) {
+  case Type::MethodTyID: {
+    unsigned Typ;
+    if (read_vbr(Buf, EndBuf, Typ)) return true;
+    const Type *RetType = getType(Typ);
+    if (RetType == 0) return true;
+
+    MethodType::ParamTypes Params;
+
+    if (read_vbr(Buf, EndBuf, Typ)) return true;
+    while (Typ) {
+      const Type *Ty = getType(Typ);
+      if (Ty == 0) return true;
+      Params.push_back(Ty);
+      
+      if (read_vbr(Buf, EndBuf, Typ)) return true;
+    }
+
+    Val = MethodType::getMethodType(RetType, Params);
+    break;
+  }
+  case Type::ArrayTyID: {
+    unsigned ElTyp;
+    if (read_vbr(Buf, EndBuf, ElTyp)) return true;
+    const Type *ElementType = getType(ElTyp);
+    if (ElementType == 0) return true;
+
+    int NumElements;
+    if (read_vbr(Buf, EndBuf, NumElements)) return true;
+    Val = ArrayType::getArrayType(ElementType, NumElements);
+    break;
+  }
+  case Type::StructTyID: {
+    unsigned Typ;
+    StructType::ElementTypes Elements;
+
+    if (read_vbr(Buf, EndBuf, Typ)) return true;
+    while (Typ) {         // List is terminated by void/0 typeid
+      const Type *Ty = getType(Typ);
+      if (Ty == 0) return true;
+      Elements.push_back(Ty);
+      
+      if (read_vbr(Buf, EndBuf, Typ)) return true;
+    }
+
+    Val = StructType::getStructType(Elements);
+    break;
+  }
+  case Type::PointerTyID: {
+    unsigned ElTyp;
+    if (read_vbr(Buf, EndBuf, ElTyp)) return true;
+    const Type *ElementType = getType(ElTyp);
+    if (ElementType == 0) return true;
+    Val = PointerType::getPointerType(ElementType);
+    break;
+  }
+
+  default:
+    cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to deserialize"
+	 << " primitive Type " << PrimType << "\n";
+    return true;
+  }
+
+  V = new ConstPoolType(Val);
+  return false;
+}
+
+bool BytecodeParser::parseConstPoolValue(const uchar *&Buf, 
+					 const uchar *EndBuf,
+					 const Type *Ty, ConstPoolVal *&V) {
+  switch (Ty->getPrimitiveID()) {
+  case Type::BoolTyID: {
+    unsigned Val;
+    if (read_vbr(Buf, EndBuf, Val)) return true;
+    if (Val != 0 && Val != 1) return true;
+    V = new ConstPoolBool(Val == 1);
+    break;
+  }
+
+  case Type::UByteTyID:   // Unsigned integer types...
+  case Type::UShortTyID:
+  case Type::UIntTyID: {
+    unsigned Val;
+    if (read_vbr(Buf, EndBuf, Val)) return true;
+    if (!ConstPoolUInt::isValueValidForType(Ty, Val)) return true;
+    V = new ConstPoolUInt(Ty, Val);
+    break;
+  }
+
+  case Type::ULongTyID: {
+    uint64_t Val;
+    if (read_vbr(Buf, EndBuf, Val)) return true;
+    V = new ConstPoolUInt(Ty, Val);
+    break;
+  }
+
+  case Type::SByteTyID:   // Unsigned integer types...
+  case Type::ShortTyID:
+  case Type::IntTyID: {
+    int Val;
+    if (read_vbr(Buf, EndBuf, Val)) return true;
+    if (!ConstPoolSInt::isValueValidForType(Ty, Val)) return 0;
+    V = new ConstPoolSInt(Ty, Val);
+    break;
+  }
+
+  case Type::LongTyID: {
+    int64_t Val;
+    if (read_vbr(Buf, EndBuf, Val)) return true;
+    V = new ConstPoolSInt(Ty, Val);
+    break;
+  }
+
+  case Type::TypeTyID:
+    if (parseTypeConstant(Buf, EndBuf, V)) return true;
+    break;
+
+  case Type::ArrayTyID: {
+    const ArrayType *AT = (const ArrayType*)Ty;
+    unsigned NumElements;
+    if (AT->isSized())          // Sized array, # elements stored in type!
+      NumElements = (unsigned)AT->getNumElements();
+    else                        // Unsized array, # elements stored in stream!
+      if (read_vbr(Buf, EndBuf, NumElements)) return true;
+
+    vector<ConstPoolVal *> Elements;
+    while (NumElements--) {   // Read all of the elements of the constant.
+      unsigned Slot;
+      if (read_vbr(Buf, EndBuf, Slot)) return true;
+      Value *V = getValue(AT->getElementType(), Slot, false);
+      if (!V || V->getValueType() != Value::ConstantVal)
+	return true;
+      Elements.push_back((ConstPoolVal*)V);
+    }
+    V = new ConstPoolArray(AT, Elements);
+    break;
+  }
+
+  case Type::StructTyID: {
+    const StructType *ST = (const StructType*)Ty;
+    const StructType::ElementTypes &ET = ST->getElementTypes();
+
+    vector<ConstPoolVal *> Elements;
+    for (unsigned i = 0; i < ET.size(); ++i) {
+      unsigned Slot;
+      if (read_vbr(Buf, EndBuf, Slot)) return true;
+      Value *V = getValue(ET[i], Slot, false);
+      if (!V || V->getValueType() != Value::ConstantVal)
+	return true;
+      Elements.push_back((ConstPoolVal*)V);      
+    }
+
+    V = new ConstPoolStruct(ST, Elements);
+    break;
+  }    
+
+  default:
+    cerr << __FILE__ << ":" << __LINE__ 
+	 << ": Don't know how to deserialize constant value of type '"
+	 << Ty->getName() << "'\n";
+    return true;
+  }
+  return false;
+}
+
+bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf,
+				       SymTabValue::ConstantPoolType &CP, 
+				       ValueTable &Tab) {
+  while (Buf < EndBuf) {
+    unsigned NumEntries, Typ;
+
+    if (read_vbr(Buf, EndBuf, NumEntries) ||
+        read_vbr(Buf, EndBuf, Typ)) return true;
+    const Type *Ty = getType(Typ);
+    if (Ty == 0) return true;
+
+    for (unsigned i = 0; i < NumEntries; i++) {
+      ConstPoolVal *I;
+      if (parseConstPoolValue(Buf, EndBuf, Ty, I)) return true;
+#if 0
+      cerr << "  Read const value: <" << I->getType()->getName() 
+	   << ">: " << I->getStrValue() << endl;
+#endif
+      insertValue(I, Tab);
+      CP.insert(I);
+    }
+  }
+  
+  return Buf > EndBuf;
+}