+
+ // We must check for a ConstantExpr before switching by type because
+ // 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 (isExprNumArgs) {
+ unsigned opCode;
+ vector<Constant*> argVec;
+ argVec.reserve(isExprNumArgs);
+
+ if (read_vbr(Buf, EndBuf, opCode)) return failure(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);
+ const Type *argTy = getType(argTypeSlot);
+ if (argTy == 0) return failure(true);
+
+ BCR_TRACE(4, "CE Arg " << i << ": Type: '" << argTy << "' slot: " << argValSlot << "\n");
+
+ // Get the arg value from its slot if it exists, otherwise a placeholder
+ Value *Val = getValue(argTy, argValSlot, false);
+ Constant* C;
+ if (Val) {
+ if (!(C = dyn_cast<Constant>(Val))) return failure(true);
+ BCR_TRACE(5, "Constant Found in ValueTable!\n");
+ } else { // Nope... find or create a forward ref. for it
+ C = fwdRefs.GetFwdRefToConstant(argTy, argValSlot);
+ }
+ argVec.push_back(C);
+ }
+
+ // Construct a ConstantExpr of the appropriate kind
+ if (isExprNumArgs == 1) { // All one-operand expressions
+ V = ConstantExpr::get(opCode, argVec[0], Ty);
+ } else if (opCode == Instruction::GetElementPtr) { // GetElementPtr
+ vector<Value*> IdxList(argVec.begin()+1, argVec.end());
+ V = ConstantExpr::get(opCode, argVec[0], IdxList, Ty);
+ } else { // All other 2-operand expressions
+ V = ConstantExpr::get(opCode, argVec[0], argVec[1], Ty);
+ }
+ return false;
+ }
+
+ // Ok, not an ConstantExpr. We now know how to read the given type...