- Finally nailed: test/Regression/Assembler/2002-08-16-ConstExprInlined.llx
authorChris Lattner <sabre@nondot.org>
Sat, 17 Aug 2002 22:01:27 +0000 (22:01 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 17 Aug 2002 22:01:27 +0000 (22:01 +0000)
    - ParseConstantPool was resolving reference to value using the function
      slot # instead of the global slot #.
  - Bytecode reader changes:
    - Remove the failure<> template from Bytecode Reader
    - Remove extraneous #includes
    - s/method/function/ a bit
    - Eliminate the fwdRefs class that just added abstraction where it was not
      needed, making things more complex.
    - Use a vector instead of a list for function signatures.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3366 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Bytecode/Reader/ConstantReader.cpp
lib/Bytecode/Reader/InstructionReader.cpp
lib/Bytecode/Reader/Reader.cpp
lib/Bytecode/Reader/ReaderInternals.h

index 37e201f2807d644b3723b7c28aa8aae483d8938b..88bfa3444a240596b9d1d3177ff1107555a1944a 100644 (file)
 
 #include "ReaderInternals.h"
 #include "llvm/Module.h"
-#include "llvm/Constants.h"
-#include "llvm/GlobalVariable.h"
 #include <algorithm>
-#include <iostream>
 
 using std::make_pair;
 
 const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf,
                                              const uchar *EndBuf) {
   unsigned PrimType;
-  if (read_vbr(Buf, EndBuf, PrimType)) return failure<const Type*>(0);
+  if (read_vbr(Buf, EndBuf, PrimType)) return 0;
 
   const Type *Val = 0;
   if ((Val = Type::getPrimitiveType((Type::PrimitiveID)PrimType)))
@@ -29,18 +26,18 @@ const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf,
   switch (PrimType) {
   case Type::FunctionTyID: {
     unsigned Typ;
-    if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
+    if (read_vbr(Buf, EndBuf, Typ)) return Val;
     const Type *RetType = getType(Typ);
-    if (RetType == 0) return failure(Val);
+    if (RetType == 0) return Val;
 
     unsigned NumParams;
-    if (read_vbr(Buf, EndBuf, NumParams)) return failure(Val);
+    if (read_vbr(Buf, EndBuf, NumParams)) return Val;
 
     std::vector<const Type*> Params;
     while (NumParams--) {
-      if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
+      if (read_vbr(Buf, EndBuf, Typ)) return Val;
       const Type *Ty = getType(Typ);
-      if (Ty == 0) return failure(Val);
+      if (Ty == 0) return Val;
       Params.push_back(Ty);
     }
 
@@ -51,12 +48,12 @@ const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf,
   }
   case Type::ArrayTyID: {
     unsigned ElTyp;
-    if (read_vbr(Buf, EndBuf, ElTyp)) return failure(Val);
+    if (read_vbr(Buf, EndBuf, ElTyp)) return Val;
     const Type *ElementType = getType(ElTyp);
-    if (ElementType == 0) return failure(Val);
+    if (ElementType == 0) return Val;
 
     unsigned NumElements;
-    if (read_vbr(Buf, EndBuf, NumElements)) return failure(Val);
+    if (read_vbr(Buf, EndBuf, NumElements)) return Val;
 
     BCR_TRACE(5, "Array Type Constant #" << ElTyp << " size=" 
               << NumElements << "\n");
@@ -66,23 +63,23 @@ const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf,
     unsigned Typ;
     std::vector<const Type*> Elements;
 
-    if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
+    if (read_vbr(Buf, EndBuf, Typ)) return Val;
     while (Typ) {         // List is terminated by void/0 typeid
       const Type *Ty = getType(Typ);
-      if (Ty == 0) return failure(Val);
+      if (Ty == 0) return Val;
       Elements.push_back(Ty);
       
-      if (read_vbr(Buf, EndBuf, Typ)) return failure(Val);
+      if (read_vbr(Buf, EndBuf, Typ)) return Val;
     }
 
     return StructType::get(Elements);
   }
   case Type::PointerTyID: {
     unsigned ElTyp;
-    if (read_vbr(Buf, EndBuf, ElTyp)) return failure(Val);
+    if (read_vbr(Buf, EndBuf, ElTyp)) return Val;
     BCR_TRACE(5, "Pointer Type Constant #" << (ElTyp-14) << "\n");
     const Type *ElementType = getType(ElTyp);
-    if (ElementType == 0) return failure(Val);
+    if (ElementType == 0) return Val;
     return PointerType::get(ElementType);
   }
 
@@ -94,7 +91,7 @@ const Type *BytecodeParser::parseTypeConstant(const uchar *&Buf,
     std::cerr << __FILE__ << ":" << __LINE__
               << ": Don't know how to deserialize"
               << " primitive Type " << PrimType << "\n";
-    return failure(Val);
+    return Val;
   }
 }
 
@@ -149,7 +146,7 @@ bool BytecodeParser::parseTypeConstants(const uchar *&Buf, const uchar *EndBuf,
   //
   for (unsigned i = 0; i < NumEntries; ++i) {
     const Type *NewTy = parseTypeConstant(Buf, EndBuf), *OldTy = Tab[i].get();
-    if (NewTy == 0) return failure(true);
+    if (NewTy == 0) return true;
     BCR_TRACE(4, "#" << i << ": Read Type Constant: '" << NewTy <<
               "' Replacing: " << OldTy << "\n");
 
@@ -184,21 +181,21 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf,
   // a ConstantExpr can be of any type, and has no explicit value.
   // 
   unsigned isExprNumArgs;               // 0 if not expr; numArgs if is expr
-  if (read_vbr(Buf, EndBuf, isExprNumArgs)) return failure(true);
+  if (read_vbr(Buf, EndBuf, isExprNumArgs)) return true;
   if (isExprNumArgs) {
     // FIXME: Encoding of constant exprs could be much more compact!
     unsigned Opcode;
     std::vector<Constant*> ArgVec;
     ArgVec.reserve(isExprNumArgs);
-    if (read_vbr(Buf, EndBuf, Opcode)) return failure(true);    
+    if (read_vbr(Buf, EndBuf, Opcode)) return true;    
 
     // Read the slot number and types of each of the arguments
     for (unsigned i = 0; i != isExprNumArgs; ++i) {
       unsigned ArgValSlot, ArgTypeSlot;
-      if (read_vbr(Buf, EndBuf, ArgValSlot)) return failure(true);
-      if (read_vbr(Buf, EndBuf, ArgTypeSlot)) return failure(true);
+      if (read_vbr(Buf, EndBuf, ArgValSlot)) return true;
+      if (read_vbr(Buf, EndBuf, ArgTypeSlot)) return true;
       const Type *ArgTy = getType(ArgTypeSlot);
-      if (ArgTy == 0) return failure(true);
+      if (ArgTy == 0) return true;
       
       BCR_TRACE(4, "CE Arg " << i << ": Type: '" << ArgTy << "'  slot: "
                 << ArgValSlot << "\n");
@@ -207,10 +204,23 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf,
       Value *Val = getValue(ArgTy, ArgValSlot, false);
       Constant *C;
       if (Val) {
-        if (!(C = dyn_cast<Constant>(Val))) return failure(true);
+        if (!(C = dyn_cast<Constant>(Val))) return true;
         BCR_TRACE(5, "Constant Found in ValueTable!\n");
       } else {         // Nope... find or create a forward ref. for it
-        C = fwdRefs.GetFwdRefToConstant(ArgTy, ArgValSlot);
+        GlobalRefsType::iterator I = GlobalRefs.find(make_pair(Ty, ArgValSlot));
+  
+        if (I != GlobalRefs.end()) {
+          BCR_TRACE(5, "Previous forward ref found!\n");
+          C = cast<Constant>(I->second);
+        } else {
+          // Create a placeholder for the constant reference and
+          // keep track of the fact that we have a forward ref to recycle it
+          BCR_TRACE(5, "Creating new forward ref to a constant!\n");
+          C = new ConstPHolder(ArgTy, ArgValSlot);
+
+          // Keep track of the fact that we have a forward ref to recycle it
+          GlobalRefs.insert(make_pair(make_pair(ArgTy, ArgValSlot), C));
+        }
       }
       ArgVec.push_back(C);
     }
@@ -232,8 +242,8 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf,
   switch (Ty->getPrimitiveID()) {
   case Type::BoolTyID: {
     unsigned Val;
-    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
-    if (Val != 0 && Val != 1) return failure(true);
+    if (read_vbr(Buf, EndBuf, Val)) return true;
+    if (Val != 0 && Val != 1) return true;
     V = ConstantBool::get(Val == 1);
     break;
   }
@@ -242,15 +252,15 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf,
   case Type::UShortTyID:
   case Type::UIntTyID: {
     unsigned Val;
-    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
-    if (!ConstantUInt::isValueValidForType(Ty, Val)) return failure(true);
+    if (read_vbr(Buf, EndBuf, Val)) return true;
+    if (!ConstantUInt::isValueValidForType(Ty, Val)) return true;
     V = ConstantUInt::get(Ty, Val);
     break;
   }
 
   case Type::ULongTyID: {
     uint64_t Val;
-    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
+    if (read_vbr(Buf, EndBuf, Val)) return true;
     V = ConstantUInt::get(Ty, Val);
     break;
   }
@@ -259,29 +269,29 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf,
   case Type::ShortTyID:
   case Type::IntTyID: {
     int Val;
-    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
-    if (!ConstantSInt::isValueValidForType(Ty, Val)) return failure(true);
+    if (read_vbr(Buf, EndBuf, Val)) return true;
+    if (!ConstantSInt::isValueValidForType(Ty, Val)) return true;
     V = ConstantSInt::get(Ty, Val);
     break;
   }
 
   case Type::LongTyID: {
     int64_t Val;
-    if (read_vbr(Buf, EndBuf, Val)) return failure(true);
+    if (read_vbr(Buf, EndBuf, Val)) return true;
     V = ConstantSInt::get(Ty, Val);
     break;
   }
 
   case Type::FloatTyID: {
     float F;
-    if (input_data(Buf, EndBuf, &F, &F+1)) return failure(true);
+    if (input_data(Buf, EndBuf, &F, &F+1)) return true;
     V = ConstantFP::get(Ty, F);
     break;
   }
 
   case Type::DoubleTyID: {
     double Val;
-    if (input_data(Buf, EndBuf, &Val, &Val+1)) return failure(true);
+    if (input_data(Buf, EndBuf, &Val, &Val+1)) return true;
     V = ConstantFP::get(Ty, Val);
     break;
   }
@@ -297,9 +307,9 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf,
     std::vector<Constant*> Elements;
     while (NumElements--) {   // Read all of the elements of the constant.
       unsigned Slot;
-      if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
+      if (read_vbr(Buf, EndBuf, Slot)) return true;
       Value *V = getValue(AT->getElementType(), Slot, false);
-      if (!V || !isa<Constant>(V)) return failure(true);
+      if (!V || !isa<Constant>(V)) return true;
       Elements.push_back(cast<Constant>(V));
     }
     V = ConstantArray::get(AT, Elements);
@@ -313,10 +323,10 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf,
     std::vector<Constant *> Elements;
     for (unsigned i = 0; i < ET.size(); ++i) {
       unsigned Slot;
-      if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
+      if (read_vbr(Buf, EndBuf, Slot)) return true;
       Value *V = getValue(ET[i], Slot, false);
       if (!V || !isa<Constant>(V))
-       return failure(true);
+       return true;
       Elements.push_back(cast<Constant>(V));      
     }
 
@@ -327,7 +337,7 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf,
   case Type::PointerTyID: {
     const PointerType *PT = cast<const PointerType>(Ty);
     unsigned SubClass;
-    if (read_vbr(Buf, EndBuf, SubClass)) return failure(true);
+    if (read_vbr(Buf, EndBuf, SubClass)) return true;
     switch (SubClass) {
     case 0:    // ConstantPointerNull value...
       V = ConstantPointerNull::get(PT);
@@ -335,17 +345,35 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf,
 
     case 1: {  // ConstantPointerRef value...
       unsigned Slot;
-      if (read_vbr(Buf, EndBuf, Slot)) return failure(true);
+      if (read_vbr(Buf, EndBuf, Slot)) return true;
       BCR_TRACE(4, "CPR: Type: '" << Ty << "'  slot: " << Slot << "\n");
 
-      // Check to see if we have already read this global variable yet...
+      // Check to see if we have already read this global variable...
       Value *Val = getValue(PT, Slot, false);
-      GlobalValueGV;
+      GlobalValue *GV;
       if (Val) {
-        if (!(GV = dyn_cast<GlobalValue>(Val))) return failure(true);
+        if (!(GV = dyn_cast<GlobalValue>(Val))) return true;
         BCR_TRACE(5, "Value Found in ValueTable!\n");
       } else {         // Nope... find or create a forward ref. for it
-        GV = fwdRefs.GetFwdRefToGlobal(PT, Slot);
+        GlobalRefsType::iterator I = GlobalRefs.find(make_pair(PT, Slot));
+
+        if (I != GlobalRefs.end()) {
+          BCR_TRACE(5, "Previous forward ref found!\n");
+          GV = cast<GlobalValue>(I->second);
+        } else {
+          BCR_TRACE(5, "Creating new forward ref to a global variable!\n");
+
+         // Create a placeholder for the global variable reference...
+          GlobalVariable *GVar =
+            new GlobalVariable(PT->getElementType(), false, true);
+          
+         // Keep track of the fact that we have a forward ref to recycle it
+          GlobalRefs.insert(make_pair(make_pair(PT, Slot), GVar));
+          
+          // Must temporarily push this value into the module table...
+          TheModule->getGlobalList().push_back(GVar);
+          GV = GVar;
+        }
       }
       V = ConstantPointerRef::get(GV);
       break;
@@ -353,7 +381,7 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf,
     
     default:
       BCR_TRACE(5, "UNKNOWN Pointer Constant Type!\n");
-      return failure(true);
+      return true;
     }
     break;
   }
@@ -362,7 +390,7 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf,
     std::cerr << __FILE__ << ":" << __LINE__ 
               << ": Don't know how to deserialize constant value of type '"
               << Ty->getName() << "'\n";
-    return failure(true);
+    return true;
   }
 
   return false;
@@ -375,9 +403,9 @@ bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf,
     unsigned NumEntries, Typ;
 
     if (read_vbr(Buf, EndBuf, NumEntries) ||
-        read_vbr(Buf, EndBuf, Typ)) return failure(true);
+        read_vbr(Buf, EndBuf, Typ)) return true;
     const Type *Ty = getType(Typ);
-    if (Ty == 0) return failure(true);
+    if (Ty == 0) return true;
     BCR_TRACE(3, "Type: '" << Ty << "'  NumEntries: " << NumEntries << "\n");
 
     if (Typ == Type::TypeTyID) {
@@ -386,15 +414,22 @@ bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf,
       for (unsigned i = 0; i < NumEntries; ++i) {
        Constant *I;
         int Slot;
-       if (parseConstantValue(Buf, EndBuf, Ty, I)) return failure(true);
-        assert(I && "parseConstantValue returned `!failure' and NULL result");
+       if (parseConstantValue(Buf, EndBuf, Ty, I)) return true;
+        assert(I && "parseConstantValue returned NULL!");
        BCR_TRACE(4, "Read Constant: '" << I << "'\n");
-       if ((Slot = insertValue(I, Tab)) < 0) return failure(true);
-        resolveRefsToConstant(I, (unsigned) Slot);
+       if ((Slot = insertValue(I, Tab)) < 0) return true;
+
+        // If we are reading a function constant table, make sure that we adjust
+        // the slot number to be the real global constant number.
+        //
+        if (&Tab != &ModuleValues)
+          Slot += ModuleValues[Typ].size();
+
+        ResolveReferencesToValue(I, (unsigned)Slot);
       }
     }
   }
   
-  if (Buf > EndBuf) return failure(true);
+  if (Buf > EndBuf) return true;
   return false;
 }
index 0de8f39c579dffd2b97d1f156081b3ad768bb963..979b3944bc28262d92e7c917e498a8a74094b2b4 100644 (file)
 #include "llvm/iMemory.h"
 #include "llvm/iPHINode.h"
 #include "llvm/iOther.h"
-#include <iostream>
 using std::vector;
 using std::cerr;
 
 bool BytecodeParser::ParseRawInst(const uchar *&Buf, const uchar *EndBuf, 
                                  RawInst &Result) {
   unsigned Op, Typ;
-  if (read(Buf, EndBuf, Op)) return failure(true);
+  if (read(Buf, EndBuf, Op)) return true;
 
   // bits   Instruction format:        Common to all formats
   // --------------------------
@@ -70,40 +69,40 @@ bool BytecodeParser::ParseRawInst(const uchar *&Buf, const uchar *EndBuf,
     break;
   case 0:
     Buf -= 4;  // Hrm, try this again...
-    if (read_vbr(Buf, EndBuf, Result.Opcode)) return failure(true);
+    if (read_vbr(Buf, EndBuf, Result.Opcode)) return true;
     Result.Opcode >>= 2;
-    if (read_vbr(Buf, EndBuf, Typ)) return failure(true);
+    if (read_vbr(Buf, EndBuf, Typ)) return true;
     Result.Ty = getType(Typ);
-    if (Result.Ty == 0) return failure(true);
-    if (read_vbr(Buf, EndBuf, Result.NumOperands)) return failure(true);
+    if (Result.Ty == 0) return true;
+    if (read_vbr(Buf, EndBuf, Result.NumOperands)) return true;
 
     switch (Result.NumOperands) {
     case 0: 
       cerr << "Zero Arg instr found!\n"; 
-      return failure(true);  // This encoding is invalid!
+      return true;  // This encoding is invalid!
     case 1: 
-      if (read_vbr(Buf, EndBuf, Result.Arg1)) return failure(true);
+      if (read_vbr(Buf, EndBuf, Result.Arg1)) return true;
       break;
     case 2:
       if (read_vbr(Buf, EndBuf, Result.Arg1) || 
-         read_vbr(Buf, EndBuf, Result.Arg2)) return failure(true);
+         read_vbr(Buf, EndBuf, Result.Arg2)) return true;
       break;
     case 3:
       if (read_vbr(Buf, EndBuf, Result.Arg1) || 
          read_vbr(Buf, EndBuf, Result.Arg2) ||
-          read_vbr(Buf, EndBuf, Result.Arg3)) return failure(true);
+          read_vbr(Buf, EndBuf, Result.Arg3)) return true;
       break;
     default:
       if (read_vbr(Buf, EndBuf, Result.Arg1) || 
-         read_vbr(Buf, EndBuf, Result.Arg2)) return failure(true);
+         read_vbr(Buf, EndBuf, Result.Arg2)) return true;
 
       // Allocate a vector to hold arguments 3, 4, 5, 6 ...
       Result.VarArgs = new vector<unsigned>(Result.NumOperands-2);
       for (unsigned a = 0; a < Result.NumOperands-2; a++)
-       if (read_vbr(Buf, EndBuf, (*Result.VarArgs)[a])) return failure(true);
+       if (read_vbr(Buf, EndBuf, (*Result.VarArgs)[a])) return true;
       break;
     }
-    if (align32(Buf, EndBuf)) return failure(true);
+    if (align32(Buf, EndBuf)) return true;
     break;
   }
 
@@ -120,7 +119,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
                                      Instruction *&Res) {
   RawInst Raw;
   if (ParseRawInst(Buf, EndBuf, Raw))
-    return failure(true);
+    return true;
 
   if (Raw.Opcode >= Instruction::FirstBinaryOp &&
       Raw.Opcode <  Instruction::NumBinaryOps  && Raw.NumOperands == 2) {
@@ -146,7 +145,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
     case 1: 
     case 3: cerr << "Invalid phi node encountered!\n"; 
             delete PN; 
-           return failure(true);
+           return true;
     case 2: PN->addIncoming(getValue(Raw.Ty, Raw.Arg1),
                            cast<BasicBlock>(getValue(Type::LabelTy,Raw.Arg2)));
       break;
@@ -156,7 +155,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
       if (Raw.VarArgs->size() & 1) {
        cerr << "PHI Node with ODD number of arguments!\n";
        delete PN;
-       return failure(true);
+       return true;
       } else {
         vector<unsigned> &args = *Raw.VarArgs;
         for (unsigned i = 0; i < args.size(); i+=2)
@@ -206,7 +205,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
     if (Raw.NumOperands == 3 || Raw.VarArgs->size() & 1) {
       cerr << "Switch statement with odd number of arguments!\n";
       delete I;
-      return failure(true);
+      return true;
     }      
     
     vector<unsigned> &args = *Raw.VarArgs;
@@ -220,13 +219,13 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
 
   case Instruction::Call: {
     Value *M = getValue(Raw.Ty, Raw.Arg1);
-    if (M == 0) return failure(true);
+    if (M == 0) return true;
 
     // Check to make sure we have a pointer to method type
     const PointerType *PTy = dyn_cast<PointerType>(M->getType());
-    if (PTy == 0) return failure(true);
+    if (PTy == 0) return true;
     const FunctionType *MTy = dyn_cast<FunctionType>(PTy->getElementType());
-    if (MTy == 0) return failure(true);
+    if (MTy == 0) return true;
 
     vector<Value *> Params;
     const FunctionType::ParamTypes &PL = MTy->getParamTypes();
@@ -236,39 +235,39 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
 
       switch (Raw.NumOperands) {
       case 0: cerr << "Invalid call instruction encountered!\n";
-       return failure(true);
+       return true;
       case 1: break;
       case 2: Params.push_back(getValue(*It++, Raw.Arg2)); break;
       case 3: Params.push_back(getValue(*It++, Raw.Arg2)); 
-       if (It == PL.end()) return failure(true);
+       if (It == PL.end()) return true;
        Params.push_back(getValue(*It++, Raw.Arg3)); break;
       default:
        Params.push_back(getValue(*It++, Raw.Arg2));
        {
          vector<unsigned> &args = *Raw.VarArgs;
          for (unsigned i = 0; i < args.size(); i++) {
-           if (It == PL.end()) return failure(true);
+           if (It == PL.end()) return true;
            // TODO: Check getValue for null!
            Params.push_back(getValue(*It++, args[i]));
          }
        }
        delete Raw.VarArgs;
       }
-      if (It != PL.end()) return failure(true);
+      if (It != PL.end()) return true;
     } else {
       if (Raw.NumOperands > 2) {
        vector<unsigned> &args = *Raw.VarArgs;
-       if (args.size() < 1) return failure(true);
+       if (args.size() < 1) return true;
 
        if ((args.size() & 1) != 0)
-         return failure(true);  // Must be pairs of type/value
+         return true;  // Must be pairs of type/value
        for (unsigned i = 0; i < args.size(); i+=2) {
          const Type *Ty = getType(args[i]);
          if (Ty == 0)
-           return failure(true);
+           return true;
          
          Value *V = getValue(Ty, args[i+1]);
-         if (V == 0) return failure(true);
+         if (V == 0) return true;
          Params.push_back(V);
        }
        delete Raw.VarArgs;
@@ -280,13 +279,13 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
   }
   case Instruction::Invoke: {
     Value *M = getValue(Raw.Ty, Raw.Arg1);
-    if (M == 0) return failure(true);
+    if (M == 0) return true;
 
     // Check to make sure we have a pointer to method type
     const PointerType *PTy = dyn_cast<PointerType>(M->getType());
-    if (PTy == 0) return failure(true);
+    if (PTy == 0) return true;
     const FunctionType *MTy = dyn_cast<FunctionType>(PTy->getElementType());
-    if (MTy == 0) return failure(true);
+    if (MTy == 0) return true;
 
     vector<Value *> Params;
     const FunctionType::ParamTypes &PL = MTy->getParamTypes();
@@ -295,27 +294,27 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
     BasicBlock *Normal, *Except;
 
     if (!MTy->isVarArg()) {
-      if (Raw.NumOperands < 3) return failure(true);
+      if (Raw.NumOperands < 3) return true;
 
       Normal = cast<BasicBlock>(getValue(Type::LabelTy, Raw.Arg2));
       Except = cast<BasicBlock>(getValue(Type::LabelTy, args[0]));
 
       FunctionType::ParamTypes::const_iterator It = PL.begin();
       for (unsigned i = 1; i < args.size(); i++) {
-       if (It == PL.end()) return failure(true);
+       if (It == PL.end()) return true;
        // TODO: Check getValue for null!
        Params.push_back(getValue(*It++, args[i]));
       }
 
-      if (It != PL.end()) return failure(true);
+      if (It != PL.end()) return true;
     } else {
-      if (args.size() < 4) return failure(true);
+      if (args.size() < 4) return true;
 
       Normal = cast<BasicBlock>(getValue(Type::LabelTy, args[0]));
       Except = cast<BasicBlock>(getValue(Type::LabelTy, args[2]));
 
       if ((args.size() & 1) != 0)
-       return failure(true);  // Must be pairs of type/value
+       return true;  // Must be pairs of type/value
       for (unsigned i = 4; i < args.size(); i+=2) {
        // TODO: Check getValue for null!
        Params.push_back(getValue(getType(args[i]), args[i+1]));
@@ -327,62 +326,62 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
     return false;
   }
   case Instruction::Malloc:
-    if (Raw.NumOperands > 2) return failure(true);
+    if (Raw.NumOperands > 2) return true;
     V = Raw.NumOperands ? getValue(Type::UIntTy, Raw.Arg1) : 0;
     Res = new MallocInst(Raw.Ty, V);
     return false;
 
   case Instruction::Alloca:
-    if (Raw.NumOperands > 2) return failure(true);
+    if (Raw.NumOperands > 2) return true;
     V = Raw.NumOperands ? getValue(Type::UIntTy, Raw.Arg1) : 0;
     Res = new AllocaInst(Raw.Ty, V);
     return false;
 
   case Instruction::Free:
     V = getValue(Raw.Ty, Raw.Arg1);
-    if (!isa<PointerType>(V->getType())) return failure(true);
+    if (!isa<PointerType>(V->getType())) return true;
     Res = new FreeInst(V);
     return false;
 
   case Instruction::Load:
   case Instruction::GetElementPtr: {
     vector<Value*> Idx;
-    if (!isa<PointerType>(Raw.Ty)) return failure(true);
+    if (!isa<PointerType>(Raw.Ty)) return true;
     const CompositeType *TopTy = dyn_cast<CompositeType>(Raw.Ty);
 
     switch (Raw.NumOperands) {
-    case 0: cerr << "Invalid load encountered!\n"; return failure(true);
+    case 0: cerr << "Invalid load encountered!\n"; return true;
     case 1: break;
     case 2:
-      if (!TopTy) return failure(true);
+      if (!TopTy) return true;
       Idx.push_back(V = getValue(TopTy->getIndexType(), Raw.Arg2));
-      if (!V) return failure(true);
+      if (!V) return true;
       break;
     case 3: {
-      if (!TopTy) return failure(true);
+      if (!TopTy) return true;
       Idx.push_back(V = getValue(TopTy->getIndexType(), Raw.Arg2));
-      if (!V) return failure(true);
+      if (!V) return true;
 
       const Type *ETy = MemAccessInst::getIndexedType(TopTy, Idx, true);
       const CompositeType *ElTy = dyn_cast_or_null<CompositeType>(ETy);
-      if (!ElTy) return failure(true);
+      if (!ElTy) return true;
 
       Idx.push_back(V = getValue(ElTy->getIndexType(), Raw.Arg3));
-      if (!V) return failure(true);
+      if (!V) return true;
       break;
     }
     default:
-      if (!TopTy) return failure(true);
+      if (!TopTy) return true;
       Idx.push_back(V = getValue(TopTy->getIndexType(), Raw.Arg2));
-      if (!V) return failure(true);
+      if (!V) return true;
 
       vector<unsigned> &args = *Raw.VarArgs;
       for (unsigned i = 0, E = args.size(); i != E; ++i) {
         const Type *ETy = MemAccessInst::getIndexedType(Raw.Ty, Idx, true);
         const CompositeType *ElTy = dyn_cast_or_null<CompositeType>(ETy);
-        if (!ElTy) return failure(true);
+        if (!ElTy) return true;
        Idx.push_back(V = getValue(ElTy->getIndexType(), args[i]));
-       if (!V) return failure(true);
+       if (!V) return true;
       }
       delete Raw.VarArgs; 
       break;
@@ -400,17 +399,17 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
   }
   case Instruction::Store: {
     vector<Value*> Idx;
-    if (!isa<PointerType>(Raw.Ty)) return failure(true);
+    if (!isa<PointerType>(Raw.Ty)) return true;
     const CompositeType *TopTy = dyn_cast<CompositeType>(Raw.Ty);
 
     switch (Raw.NumOperands) {
     case 0: 
-    case 1: cerr << "Invalid store encountered!\n"; return failure(true);
+    case 1: cerr << "Invalid store encountered!\n"; return true;
     case 2: break;
     case 3:
-      if (!TopTy) return failure(true);
+      if (!TopTy) return true;
       Idx.push_back(V = getValue(TopTy->getIndexType(), Raw.Arg3));
-      if (!V) return failure(true);
+      if (!V) return true;
       break;
     default:
       vector<unsigned> &args = *Raw.VarArgs;
@@ -418,20 +417,20 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
       unsigned i, E;
       for (i = 0, E = args.size(); ElTy && i != E; ++i) {
        Idx.push_back(V = getValue(ElTy->getIndexType(), args[i]));
-       if (!V) return failure(true);
+       if (!V) return true;
 
         const Type *ETy = MemAccessInst::getIndexedType(Raw.Ty, Idx, true);
         ElTy = dyn_cast_or_null<CompositeType>(ETy);
       }
       if (i != E)
-        return failure(true);  // didn't use up all of the indices!
+        return true;  // didn't use up all of the indices!
 
       delete Raw.VarArgs; 
       break;
     }
 
     const Type *ElType = StoreInst::getIndexedType(Raw.Ty, Idx);
-    if (ElType == 0) return failure(true);
+    if (ElType == 0) return true;
     Res = new StoreInst(getValue(ElType, Raw.Arg1), getValue(Raw.Ty, Raw.Arg2),
                        Idx);
     return false;
@@ -440,5 +439,5 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
 
   cerr << "Unrecognized instruction! " << Raw.Opcode 
        << " ADDR = 0x" << (void*)Buf << "\n";
-  return failure(true);
+  return true;
 }
index 8d4ad5640651cc5ed835b186f693e0c05175afe5..0e406259769c5c306aab8905e78858f119b36568 100644 (file)
@@ -5,7 +5,7 @@
 // Note that this library should be as fast as possible, reentrant, and 
 // threadsafe!!
 //
-// TODO: Make error message outputs be configurable depending on an option?
+// TODO: Return error messages to caller instead of printing them out directly.
 // TODO: Allow passing in an option to ignore the symbol table
 //
 //===----------------------------------------------------------------------===//
@@ -13,7 +13,6 @@
 #include "ReaderInternals.h"
 #include "llvm/Bytecode/Reader.h"
 #include "llvm/Bytecode/Format.h"
-#include "llvm/GlobalVariable.h"
 #include "llvm/Module.h"
 #include "llvm/Constants.h"
 #include "llvm/iPHINode.h"
@@ -24,7 +23,6 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <algorithm>
-#include <iostream>
 using std::cerr;
 using std::pair;
 using std::make_pair;
@@ -56,14 +54,14 @@ const Type *BytecodeParser::getType(unsigned ID) {
   //cerr << "Looking up Type ID: " << ID << "\n";
 
   const Value *D = getValue(Type::TypeTy, ID, false);
-  if (D == 0) return failure<const Type*>(0);
+  if (D == 0) return 0;
 
   return cast<Type>(D);
 }
 
 int BytecodeParser::insertValue(Value *Val, std::vector<ValueList> &ValueTab) {
   unsigned type;
-  if (getTypeSlot(Val->getType(), type)) return failure<int>(-1);
+  if (getTypeSlot(Val->getType(), type)) return -1;
   assert(type != Type::TypeTyID && "Types should never be insertValue'd!");
  
   if (ValueTab.size() <= type)
@@ -80,7 +78,7 @@ Value *BytecodeParser::getValue(const Type *Ty, unsigned oNum, bool Create) {
   unsigned Num = oNum;
   unsigned type;   // The type plane it lives in...
 
-  if (getTypeSlot(Ty, type)) return failure<Value*>(0); // TODO: true
+  if (getTypeSlot(Ty, type)) return 0;
 
   if (type == Type::TypeTyID) {  // The 'type' plane has implicit values
     assert(Create == false);
@@ -111,22 +109,26 @@ Value *BytecodeParser::getValue(const Type *Ty, unsigned oNum, bool Create) {
   if (Values.size() > type && Values[type].size() > Num)
     return Values[type][Num];
 
-  if (!Create) return failure<Value*>(0);  // Do not create a placeholder?
+  if (!Create) return 0;  // Do not create a placeholder?
 
   Value *d = 0;
   switch (Ty->getPrimitiveID()) {
-  case Type::LabelTyID: d = new    BBPHolder(Ty, oNum); break;
   case Type::FunctionTyID:
     cerr << "Creating method pholder! : " << type << ":" << oNum << " " 
         << Ty->getName() << "\n";
-    d = new MethPHolder(Ty, oNum);
-    if (insertValue(d, LateResolveModuleValues) ==-1) return failure<Value*>(0);
+    d = new FunctionPHolder(Ty, oNum);
+    if (insertValue(d, LateResolveModuleValues) == -1) return 0;
     return d;
-  default:                   d = new   DefPHolder(Ty, oNum); break;
+  case Type::LabelTyID:
+    d = new BBPHolder(Ty, oNum);
+    break;
+  default:
+    d = new ValPHolder(Ty, oNum);
+    break;
   }
 
   assert(d != 0 && "How did we not make something?");
-  if (insertValue(d, LateResolveValues) == -1) return failure<Value*>(0);
+  if (insertValue(d, LateResolveValues) == -1) return 0;
   return d;
 }
 
@@ -168,11 +170,11 @@ bool BytecodeParser::ParseBasicBlock(const uchar *&Buf, const uchar *EndBuf,
     Instruction *Inst;
     if (ParseInstruction(Buf, EndBuf, Inst)) {
       delete BB;
-      return failure(true);
+      return true;
     }
 
-    if (Inst == 0) { delete BB; return failure(true); }
-    if (insertValue(Inst, Values) == -1) { delete BB; return failure(true); }
+    if (Inst == 0) { delete BB; return true; }
+    if (insertValue(Inst, Values) == -1) { delete BB; return true; }
 
     BB->getInstList().push_back(Inst);
 
@@ -188,9 +190,9 @@ bool BytecodeParser::ParseSymbolTable(const uchar *&Buf, const uchar *EndBuf,
     // Symtab block header: [num entries][type id number]
     unsigned NumEntries, Typ;
     if (read_vbr(Buf, EndBuf, NumEntries) ||
-        read_vbr(Buf, EndBuf, Typ)) return failure(true);
+        read_vbr(Buf, EndBuf, Typ)) return true;
     const Type *Ty = getType(Typ);
-    if (Ty == 0) return failure(true);
+    if (Ty == 0) return true;
 
     BCR_TRACE(3, "Plane Type: '" << Ty << "' with " << NumEntries <<
              " entries\n");
@@ -198,15 +200,15 @@ bool BytecodeParser::ParseSymbolTable(const uchar *&Buf, const uchar *EndBuf,
     for (unsigned i = 0; i < NumEntries; ++i) {
       // Symtab entry: [def slot #][name]
       unsigned slot;
-      if (read_vbr(Buf, EndBuf, slot)) return failure(true);
+      if (read_vbr(Buf, EndBuf, slot)) return true;
       std::string Name;
       if (read(Buf, EndBuf, Name, false))  // Not aligned...
-       return failure(true);
+       return true;
 
       Value *D = getValue(Ty, slot, false); // Find mapping...
       if (D == 0) {
        BCR_TRACE(3, "FAILED LOOKUP: Slot #" << slot << "\n");
-       return failure(true);
+       return true;
       }
       BCR_TRACE(4, "Map: '" << Name << "' to #" << slot << ":" << D;
                if (!isa<Instruction>(D)) cerr << "\n");
@@ -215,141 +217,53 @@ bool BytecodeParser::ParseSymbolTable(const uchar *&Buf, const uchar *EndBuf,
     }
   }
 
-  if (Buf > EndBuf) return failure(true);
+  if (Buf > EndBuf) return true;
   return false;
 }
 
-Value*
-ConstantFwdRefs::find(const Type* Ty, unsigned Slot) {
-  GlobalRefsType::iterator I = GlobalRefs.find(make_pair(Ty, Slot));
-  if (I != GlobalRefs.end()) {
-    return I->second;
-  } else {
-    return failure<Value*>(0);
-  }
-}
+void BytecodeParser::ResolveReferencesToValue(Value *NewV, unsigned Slot) {
+  GlobalRefsType::iterator I = GlobalRefs.find(make_pair(NewV->getType(),Slot));
+  if (I == GlobalRefs.end()) return;   // Never forward referenced?
 
-void
-ConstantFwdRefs::insert(const Type* Ty, unsigned Slot, Value* V) {
-  // Keep track of the fact that we have a forward ref to recycle it
-  const pair<GlobalRefsType::iterator, bool>& result =
-    GlobalRefs.insert(make_pair(make_pair(Ty, Slot), V));
-  assert(result.second == true && "Entry already exists for this slot?");
-}
+  BCR_TRACE(3, "Mutating forward refs!\n");
+  Value *VPH = I->second;   // Get the placeholder...
 
-void
-ConstantFwdRefs::erase(const Type* Ty, unsigned Slot) {
-  GlobalRefsType::iterator I = GlobalRefs.find(make_pair(Ty, Slot));
-  if (I != GlobalRefs.end())
-    GlobalRefs.erase(I);
-}
-
-// GetFwdRefToConstant - Get a forward reference to a constant value.
-//                       Create a unique one if it does not exist already.
-// 
-Constant*
-ConstantFwdRefs::GetFwdRefToConstant(const Type* Ty, unsigned Slot) {
-  
-  Constant* C = cast_or_null<Constant>(find(Ty, Slot));
-  
-  if (C) {
-    BCR_TRACE(5, "Previous forward ref found!\n");
-  } else {
-    // Create a placeholder for the constant reference and
-    // keep track of the fact that we have a forward ref to recycle it
-    BCR_TRACE(5, "Creating new forward ref to a constant!\n");
-    C = new ConstPHolder(Ty, Slot);
-    insert(Ty, Slot, C);
-  }
-  
-  return C;
-}
-
-
-// GetFwdRefToGlobal - Get a forward reference to a global value.
-//                     Create a unique one if it does not exist already.
-// 
-GlobalValue*
-ConstantFwdRefs::GetFwdRefToGlobal(const PointerType* PT, unsigned Slot) {
-  
-  GlobalValue* GV = cast_or_null<GlobalValue>(find(PT, Slot));
-
-  if (GV) {
-    BCR_TRACE(5, "Previous forward ref found!\n");
-  } else {
-    BCR_TRACE(5, "Creating new forward ref to a global variable!\n");
-
-         // Create a placeholder for the global variable reference...
-    GlobalVariable *GVar =
-      new GlobalVariable(PT->getElementType(), false, true);
-
-         // Keep track of the fact that we have a forward ref to recycle it
-    insert(PT, Slot, GVar);
-  
-    // Must temporarily push this value into the module table...
-    TheModule->getGlobalList().push_back(GVar);
-    GV = GVar;
-  }
-
-  return GV;
-}
-
-void
-ConstantFwdRefs::ResolveRefsToValue(Value* NewV, unsigned Slot) {
-  if (Value* vph = find(NewV->getType(), Slot)) {
-    BCR_TRACE(3, "Mutating forward refs!\n");
-
-    // Loop over all of the uses of the Value.  What they are depends
-    // on what NewV is.  Replacing a use of the old reference takes the
-    // use off the use list, so loop with !use_empty(), not the use_iterator.
-    while (!vph->use_empty()) {
-      Constant *C = cast<Constant>(vph->use_back());
-      unsigned numReplaced = C->mutateReferences(vph, NewV);
-      assert(numReplaced > 0 && "Supposed user wasn't really a user?");
+  // Loop over all of the uses of the Value.  What they are depends
+  // on what NewV is.  Replacing a use of the old reference takes the
+  // use off the use list, so loop with !use_empty(), not the use_iterator.
+  while (!VPH->use_empty()) {
+    Constant *C = cast<Constant>(VPH->use_back());
+    unsigned numReplaced = C->mutateReferences(VPH, NewV);
+    assert(numReplaced > 0 && "Supposed user wasn't really a user?");
       
-      if (GlobalValue* GVal = dyn_cast<GlobalValue>(NewV)) {
-        // Remove the placeholder GlobalValue from the module...
-        GVal->getParent()->getGlobalList().remove(cast<GlobalVariable>(vph));
-      }
+    if (GlobalValue* GVal = dyn_cast<GlobalValue>(NewV)) {
+      // Remove the placeholder GlobalValue from the module...
+      GVal->getParent()->getGlobalList().remove(cast<GlobalVariable>(VPH));
     }
-
-    delete vph;                         // Delete the old placeholder
-    erase(NewV->getType(), Slot);       // Remove the map entry for it
   }
-}
-
-// resolveRefsToGlobal - Patch up forward references to global values in the
-// form of ConstantPointerRef.
-//
-void BytecodeParser::resolveRefsToGlobal(GlobalValue *GV, unsigned Slot) {
-  fwdRefs.ResolveRefsToValue(GV, Slot);
-}
 
-// resolveRefsToConstant - Patch up forward references to constants
-//
-void BytecodeParser::resolveRefsToConstant(Constant *C, unsigned Slot) {
-  fwdRefs.ResolveRefsToValue(C, Slot);
+  delete VPH;                         // Delete the old placeholder
+  GlobalRefs.erase(I);                // Remove the map entry for it
 }
 
-
 bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf, 
                                 Module *C) {
   // Clear out the local values table...
   Values.clear();
-  if (MethodSignatureList.empty()) {
+  if (FunctionSignatureList.empty()) {
     Error = "Function found, but FunctionSignatureList empty!";
-    return failure(true);  // Unexpected method!
+    return true;  // Unexpected method!
   }
 
-  const PointerType *PMTy = MethodSignatureList.front().first; // PtrMeth
+  const PointerType *PMTy = FunctionSignatureList.back().first; // PtrMeth
   const FunctionType *MTy  = dyn_cast<FunctionType>(PMTy->getElementType());
-  if (MTy == 0) return failure(true);  // Not ptr to method!
+  if (MTy == 0) return true;  // Not ptr to method!
 
   unsigned isInternal;
-  if (read_vbr(Buf, EndBuf, isInternal)) return failure(true);
+  if (read_vbr(Buf, EndBuf, isInternal)) return true;
 
-  unsigned MethSlot = MethodSignatureList.front().second;
-  MethodSignatureList.pop_front();
+  unsigned MethSlot = FunctionSignatureList.back().second;
+  FunctionSignatureList.pop_back();
   Function *M = new Function(MTy, isInternal != 0);
 
   BCR_TRACE(2, "METHOD TYPE: " << MTy << "\n");
@@ -360,7 +274,7 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
     Argument *FA = new Argument(*It);
     if (insertValue(FA, Values) == -1) {
       Error = "Error reading method arguments!\n";
-      delete M; return failure(true)
+      delete M; return true
     }
     M->getArgumentList().push_back(FA);
   }
@@ -370,14 +284,14 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
     const uchar *OldBuf = Buf;
     if (readBlock(Buf, EndBuf, Type, Size)) {
       Error = "Error reading Function level block!";
-      delete M; return failure(true)
+      delete M; return true
     }
 
     switch (Type) {
     case BytecodeFormat::ConstantPool:
       BCR_TRACE(2, "BLOCK BytecodeFormat::ConstantPool: {\n");
       if (ParseConstantPool(Buf, Buf+Size, Values, MethodTypeValues)) {
-       delete M; return failure(true);
+       delete M; return true;
       }
       break;
 
@@ -386,7 +300,7 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
       BasicBlock *BB;
       if (ParseBasicBlock(Buf, Buf+Size, BB) ||
          insertValue(BB, Values) == -1) {
-       delete M; return failure(true);                // Parse error... :(
+       delete M; return true;                // Parse error... :(
       }
 
       M->getBasicBlockList().push_back(BB);
@@ -396,14 +310,14 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
     case BytecodeFormat::SymbolTable:
       BCR_TRACE(2, "BLOCK BytecodeFormat::SymbolTable: {\n");
       if (ParseSymbolTable(Buf, Buf+Size, M->getSymbolTableSure())) {
-       delete M; return failure(true);
+       delete M; return true;
       }
       break;
 
     default:
       BCR_TRACE(2, "BLOCK <unknown>:ignored! {\n");
       Buf += Size;
-      if (OldBuf > Buf) return failure(true); // Wrap around!
+      if (OldBuf > Buf) return true; // Wrap around!
       break;
     }
     BCR_TRACE(2, "} end block\n");
@@ -411,19 +325,19 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
     if (align32(Buf, EndBuf)) {
       Error = "Error aligning Function level block!";
       delete M;    // Malformed bc file, read past end of block.
-      return failure(true);
+      return true;
     }
   }
 
   if (postResolveValues(LateResolveValues) ||
       postResolveValues(LateResolveModuleValues)) {
     Error = "Error resolving method values!";
-    delete M; return failure(true);     // Unresolvable references!
+    delete M; return true;     // Unresolvable references!
   }
 
-  Value *MethPHolder = getValue(PMTy, MethSlot, false);
-  assert(MethPHolder && "Something is broken no placeholder found!");
-  assert(isa<Function>(MethPHolder) && "Not a function?");
+  Value *FunctionPHolder = getValue(PMTy, MethSlot, false);
+  assert(FunctionPHolder && "Something is broken no placeholder found!");
+  assert(isa<Function>(FunctionPHolder) && "Not a function?");
 
   unsigned type;  // Type slot
   assert(!getTypeSlot(MTy, type) && "How can meth type not exist?");
@@ -438,37 +352,37 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
   MethodTypeValues.clear();
 
   // If anyone is using the placeholder make them use the real method instead
-  MethPHolder->replaceAllUsesWith(M);
+  FunctionPHolder->replaceAllUsesWith(M);
 
   // We don't need the placeholder anymore!
-  delete MethPHolder;
+  delete FunctionPHolder;
 
   // If the method is empty, we don't need the method argument entries...
   if (M->isExternal())
     M->getArgumentList().clear();
 
-  resolveRefsToGlobal(M, MethSlot);
+  ResolveReferencesToValue(M, MethSlot);
 
   return false;
 }
 
 bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
                                           Module *Mod) {
-  if (!MethodSignatureList.empty()) {
+  if (!FunctionSignatureList.empty()) {
     Error = "Two ModuleGlobalInfo packets found!";
-    return failure(true);  // Two ModuleGlobal blocks?
+    return true;  // Two ModuleGlobal blocks?
   }
 
   // Read global variables...
   unsigned VarType;
-  if (read_vbr(Buf, End, VarType)) return failure(true);
+  if (read_vbr(Buf, End, VarType)) return true;
   while (VarType != Type::VoidTyID) { // List is terminated by Void
     // VarType Fields: bit0 = isConstant, bit1 = hasInitializer,
     // bit2 = isInternal, bit3+ = slot#
     const Type *Ty = getType(VarType >> 3);
     if (!Ty || !isa<PointerType>(Ty)) { 
       Error = "Global not pointer type!  Ty = " + Ty->getDescription();
-      return failure(true)
+      return true
     }
 
     const PointerType *PTy = cast<const PointerType>(Ty);
@@ -480,10 +394,10 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
       // which should have been read before now.
       //
       unsigned InitSlot;
-      if (read_vbr(Buf, End, InitSlot)) return failure(true);
+      if (read_vbr(Buf, End, InitSlot)) return true;
       
       Value *V = getValue(ElTy, InitSlot, false);
-      if (V == 0) return failure(true);
+      if (V == 0) return true;
       Initializer = cast<Constant>(V);
     }
 
@@ -491,28 +405,28 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
     GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, VarType & 4,
                                            Initializer);
     int DestSlot = insertValue(GV, ModuleValues);
-    if (DestSlot == -1) return failure(true);
+    if (DestSlot == -1) return true;
 
     Mod->getGlobalList().push_back(GV);
 
-    resolveRefsToGlobal(GV, unsigned(DestSlot));
+    ResolveReferencesToValue(GV, (unsigned)DestSlot);
 
     BCR_TRACE(2, "Global Variable of type: " << PTy->getDescription() 
              << " into slot #" << DestSlot << "\n");
 
-    if (read_vbr(Buf, End, VarType)) return failure(true);
+    if (read_vbr(Buf, End, VarType)) return true;
   }
 
   // Read the method signatures for all of the methods that are coming, and 
   // create fillers in the Value tables.
-  unsigned MethSignature;
-  if (read_vbr(Buf, End, MethSignature)) return failure(true);
-  while (MethSignature != Type::VoidTyID) { // List is terminated by Void
-    const Type *Ty = getType(MethSignature);
+  unsigned FnSignature;
+  if (read_vbr(Buf, End, FnSignature)) return true;
+  while (FnSignature != Type::VoidTyID) { // List is terminated by Void
+    const Type *Ty = getType(FnSignature);
     if (!Ty || !isa<PointerType>(Ty) ||
         !isa<FunctionType>(cast<PointerType>(Ty)->getElementType())) { 
       Error = "Function not ptr to func type!  Ty = " + Ty->getDescription();
-      return failure(true)
+      return true
     }
     
     // We create methods by passing the underlying FunctionType to create...
@@ -524,25 +438,29 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
     // placeholder is replaced.
 
     // Insert the placeholder...
-    Value *Val = new MethPHolder(Ty, 0);
-    if (insertValue(Val, ModuleValues) == -1) return failure(true);
+    Value *Val = new FunctionPHolder(Ty, 0);
+    if (insertValue(Val, ModuleValues) == -1) return true;
 
     // Figure out which entry of its typeslot it went into...
     unsigned TypeSlot;
-    if (getTypeSlot(Val->getType(), TypeSlot)) return failure(true);
+    if (getTypeSlot(Val->getType(), TypeSlot)) return true;
 
     unsigned SlotNo = ModuleValues[TypeSlot].size()-1;
     
     // Keep track of this information in a linked list that is emptied as 
     // methods are loaded...
     //
-    MethodSignatureList.push_back(
+    FunctionSignatureList.push_back(
            make_pair(cast<const PointerType>(Val->getType()), SlotNo));
-    if (read_vbr(Buf, End, MethSignature)) return failure(true);
+    if (read_vbr(Buf, End, FnSignature)) return true;
     BCR_TRACE(2, "Function of type: " << Ty << "\n");
   }
 
-  if (align32(Buf, End)) return failure(true);
+  if (align32(Buf, End)) return true;
+
+  // Now that the function signature list is set up, reverse it so that we can 
+  // remove elements efficiently from the back of the vector.
+  std::reverse(FunctionSignatureList.begin(), FunctionSignatureList.end());
 
   // This is for future proofing... in the future extra fields may be added that
   // we don't understand, so we transparently ignore them.
@@ -552,73 +470,72 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
 }
 
 bool BytecodeParser::ParseModule(const uchar *Buf, const uchar *EndBuf, 
-                               Module *&C) {
+                               Module *&Mod) {
 
   unsigned Type, Size;
-  if (readBlock(Buf, EndBuf, Type, Size)) return failure(true);
+  if (readBlock(Buf, EndBuf, Type, Size)) return true;
   if (Type != BytecodeFormat::Module || Buf+Size != EndBuf) {
     Error = "Expected Module packet!";
-    return failure(true);                      // Hrm, not a class?
+    return true;                      // Hrm, not a class?
   }
 
   BCR_TRACE(0, "BLOCK BytecodeFormat::Module: {\n");
-  MethodSignatureList.clear();                 // Just in case...
+  FunctionSignatureList.clear();                 // Just in case...
 
   // Read into instance variables...
-  if (read_vbr(Buf, EndBuf, FirstDerivedTyID)) return failure(true);
-  if (align32(Buf, EndBuf)) return failure(true);
+  if (read_vbr(Buf, EndBuf, FirstDerivedTyID)) return true;
+  if (align32(Buf, EndBuf)) return true;
   BCR_TRACE(1, "FirstDerivedTyID = " << FirstDerivedTyID << "\n");
 
-  TheModule = C = new Module();
-  fwdRefs.VisitingModule(TheModule);
+  TheModule = Mod = new Module();
 
   while (Buf < EndBuf) {
     const uchar *OldBuf = Buf;
-    if (readBlock(Buf, EndBuf, Type, Size)) { delete C; return failure(true); }
+    if (readBlock(Buf, EndBuf, Type, Size)) { delete Mod; return true;}
     switch (Type) {
     case BytecodeFormat::ConstantPool:
       BCR_TRACE(1, "BLOCK BytecodeFormat::ConstantPool: {\n");
       if (ParseConstantPool(Buf, Buf+Size, ModuleValues, ModuleTypeValues)) {
-       delete C; return failure(true);
+       delete Mod; return true;
       }
       break;
 
     case BytecodeFormat::ModuleGlobalInfo:
       BCR_TRACE(1, "BLOCK BytecodeFormat::ModuleGlobalInfo: {\n");
 
-      if (ParseModuleGlobalInfo(Buf, Buf+Size, C)) {
-       delete C; return failure(true);
+      if (ParseModuleGlobalInfo(Buf, Buf+Size, Mod)) {
+       delete Mod; return true;
       }
       break;
 
     case BytecodeFormat::Function: {
       BCR_TRACE(1, "BLOCK BytecodeFormat::Function: {\n");
-      if (ParseMethod(Buf, Buf+Size, C)) {
-       delete C; return failure(true);               // Error parsing method
+      if (ParseMethod(Buf, Buf+Size, Mod)) {
+       delete Mod; return true;              // Error parsing function
       }
       break;
     }
 
     case BytecodeFormat::SymbolTable:
       BCR_TRACE(1, "BLOCK BytecodeFormat::SymbolTable: {\n");
-      if (ParseSymbolTable(Buf, Buf+Size, C->getSymbolTableSure())) {
-       delete C; return failure(true);
+      if (ParseSymbolTable(Buf, Buf+Size, Mod->getSymbolTableSure())) {
+       delete Mod; return true;
       }
       break;
 
     default:
       Error = "Expected Module Block!";
       Buf += Size;
-      if (OldBuf > Buf) return failure(true); // Wrap around!
+      if (OldBuf > Buf) return true; // Wrap around!
       break;
     }
     BCR_TRACE(1, "} end block\n");
-    if (align32(Buf, EndBuf)) { delete C; return failure(true); }
+    if (align32(Buf, EndBuf)) { delete Mod; return true; }
   }
 
-  if (!MethodSignatureList.empty()) {     // Expected more methods!
+  if (!FunctionSignatureList.empty()) {     // Expected more methods!
     Error = "Function expected, but bytecode stream at end!";
-    return failure(true);
+    return true;
   }
 
   BCR_TRACE(0, "} end block\n\n");
@@ -632,7 +549,7 @@ Module *BytecodeParser::ParseBytecode(const uchar *Buf, const uchar *EndBuf) {
   if (read(Buf, EndBuf, Sig) ||
       Sig != ('l' | ('l' << 8) | ('v' << 16) | 'm' << 24)) {
     Error = "Invalid bytecode signature!";
-    return failure<Module*>(0);                          // Invalid signature!
+    return 0;                          // Invalid signature!
   }
 
   Module *Result;
@@ -656,21 +573,21 @@ Module *ParseBytecodeFile(const std::string &Filename, std::string *ErrorStr) {
     int FD = open(Filename.c_str(), O_RDONLY);
     if (FD == -1) {
       if (ErrorStr) *ErrorStr = "Error opening file!";
-      return failure<Module*>(0);
+      return 0;
     }
 
-    if (fstat(FD, &StatBuf) == -1) { close(FD); return failure<Module*>(0); }
+    if (fstat(FD, &StatBuf) == -1) { close(FD); return 0; }
 
     int Length = StatBuf.st_size;
     if (Length == 0) { 
       if (ErrorStr) *ErrorStr = "Error stat'ing file!";
-      close(FD); return failure<Module*>(0)
+      close(FD); return 0
     }
     uchar *Buffer = (uchar*)mmap(0, Length, PROT_READ, 
                                MAP_PRIVATE, FD, 0);
     if (Buffer == (uchar*)-1) {
       if (ErrorStr) *ErrorStr = "Error mmapping file!";
-      close(FD); return failure<Module*>(0);
+      close(FD); return 0;
     }
 
     BytecodeParser Parser;
@@ -684,7 +601,7 @@ Module *ParseBytecodeFile(const std::string &Filename, std::string *ErrorStr) {
     int BlockSize;
     uchar Buffer[4096], *FileData = 0;
     while ((BlockSize = read(0, Buffer, 4))) {
-      if (BlockSize == -1) { free(FileData); return failure<Module*>(0); }
+      if (BlockSize == -1) { free(FileData); return 0; }
 
       FileData = (uchar*)realloc(FileData, FileSize+BlockSize);
       memcpy(FileData+FileSize, Buffer, BlockSize);
@@ -693,7 +610,7 @@ Module *ParseBytecodeFile(const std::string &Filename, std::string *ErrorStr) {
 
     if (FileSize == 0) {
       if (ErrorStr) *ErrorStr = "Standard Input empty!";
-      free(FileData); return failure<Module*>(0);
+      free(FileData); return 0;
     }
 
 #define ALIGN_PTRS 1
index 4b1974e01963b4270a33a7724f0975e6b128d2fc..fdaf13d13c1ff993b568661497675aaac98328f4 100644 (file)
@@ -8,16 +8,11 @@
 #define READER_INTERNALS_H
 
 #include "llvm/Bytecode/Primitives.h"
-#include "llvm/Function.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/Instruction.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
 #include "llvm/Constant.h"
-#include "Support/NonCopyable.h"
-#include <map>
 #include <utility>
-#include <list>
-#include <iostream>
+#include <map>
 
 // Enable to trace to figure out what the heck is going on when parsing fails
 #define TRACE_LEVEL 0
@@ -41,38 +36,10 @@ struct RawInst {       // The raw fields out of the bytecode stream...
   };
 };
 
-
-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...
+  BytecodeParser(const BytecodeParser &);  // DO NOT IMPLEMENT
+  void operator=(const BytecodeParser &);  // DO NOT IMPLEMENT
 public:
   BytecodeParser() {
     // Define this in case we don't see a ModuleGlobalInfo block.
@@ -95,8 +62,14 @@ private:          // All of this data is transient across calls to ParseBytecode
   ValueTable Values, LateResolveValues;
   ValueTable ModuleValues, LateResolveModuleValues;
 
-  // fwdRefs - This manages forward references to global values.
-  ConstantFwdRefs fwdRefs;
+  // 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;
 
   // TypesLoaded - This vector mirrors the Values[TypeTyID] plane.  It is used
   // to deal with forward references to types.
@@ -108,12 +81,12 @@ private:          // All of this data is transient across calls to ParseBytecode
   // Information read from the ModuleGlobalInfo section of the file...
   unsigned FirstDerivedTyID;
 
-  // When the ModuleGlobalInfo section is read, we load the type of each method
-  // and the 'ModuleValues' slot that it lands in.  We then load a placeholder
-  // into its slot to reserve it.  When the method is loaded, this placeholder
-  // is replaced.
+  // When the ModuleGlobalInfo section is read, we load the type of each
+  // function and the 'ModuleValues' slot that it lands in.  We then load a
+  // placeholder into its slot to reserve it.  When the function is loaded, this
+  // placeholder is replaced.
   //
-  std::list<std::pair<const PointerType *, unsigned> > MethodSignatureList;
+  std::vector<std::pair<const PointerType *, unsigned> > FunctionSignatureList;
 
 private:
   bool ParseModule          (const uchar * Buf, const uchar *End, Module *&);
@@ -140,11 +113,9 @@ private:
 
   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);
+  // resolve all references to the placeholder (if any) for the given value
+  void ResolveReferencesToValue(Value *Val, unsigned Slot);
+
   
   // refineAbstractType - The callback method is invoked when one of the
   // elements of TypeValues becomes more concrete...
@@ -155,7 +126,8 @@ private:
 template<class SuperType>
 class PlaceholderDef : public SuperType {
   unsigned ID;
-  PlaceholderDef();                     // do not implement
+  PlaceholderDef();                       // DO NOT IMPLEMENT
+  void operator=(const PlaceholderDef &); // DO NOT IMPLEMENT
 public:
   PlaceholderDef(const Type *Ty, unsigned id) : SuperType(Ty), ID(id) {}
   unsigned getID() { return ID; }
@@ -174,8 +146,8 @@ struct BBPlaceHolderHelper : public BasicBlock {
   }
 };
 
-struct MethPlaceHolderHelper : public Function {
-  MethPlaceHolderHelper(const Type *Ty) 
+struct FunctionPlaceHolderHelper : public Function {
+  FunctionPlaceHolderHelper(const Type *Ty) 
     : Function(cast<const FunctionType>(Ty), true) {
   }
 };
@@ -186,21 +158,21 @@ struct ConstantPlaceHolderHelper : public Constant {
   virtual bool isNullValue() const { return false; }
 };
 
-typedef PlaceholderDef<InstPlaceHolderHelper>  DefPHolder;
+typedef PlaceholderDef<InstPlaceHolderHelper>  ValPHolder;
 typedef PlaceholderDef<BBPlaceHolderHelper>    BBPHolder;
-typedef PlaceholderDef<MethPlaceHolderHelper>  MethPHolder;
+typedef PlaceholderDef<FunctionPlaceHolderHelper>  FunctionPHolder;
 typedef PlaceholderDef<ConstantPlaceHolderHelper>  ConstPHolder;
 
 
-static inline unsigned getValueIDNumberFromPlaceHolder(Value *Def) {
-  if (isa<Constant>(Def))
-    return ((ConstPHolder*)Def)->getID();
+static inline unsigned getValueIDNumberFromPlaceHolder(Value *Val) {
+  if (isa<Constant>(Val))
+    return ((ConstPHolder*)Val)->getID();
   
   // else discriminate by type
-  switch (Def->getType()->getPrimitiveID()) {
-  case Type::LabelTyID:    return ((BBPHolder*)Def)->getID();
-  case Type::FunctionTyID: return ((MethPHolder*)Def)->getID();
-  default:                 return ((DefPHolder*)Def)->getID();
+  switch (Val->getType()->getPrimitiveID()) {
+  case Type::LabelTyID:    return ((BBPHolder*)Val)->getID();
+  case Type::FunctionTyID: return ((FunctionPHolder*)Val)->getID();
+  default:                 return ((ValPHolder*)Val)->getID();
   }
 }
 
@@ -216,13 +188,4 @@ static inline bool readBlock(const uchar *&Buf, const uchar *EndBuf,
 #endif
 }
 
-
-// failure Template - This template function is used as a place to put
-// breakpoints in to debug failures of the bytecode parser.
-//
-template <typename X>
-static X failure(X Value) {
-  return Value;
-}
-
 #endif