diff options
author | Chris Lattner <sabre@nondot.org> | 2007-04-24 05:48:56 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-04-24 05:48:56 +0000 |
commit | 522b7b104c864da81c19d8b16c43b7a1f6a2fc40 (patch) | |
tree | b3466074088bcbf9feee242542d7938cc639a235 /lib/Bitcode/Reader/BitcodeReader.cpp | |
parent | 0eef08046e0758f1800f32c63b817fd22264577b (diff) |
implement support for reading aggregate constants, including handling forward
constant references, etc.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36391 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index d974ace209..fa75e00e6c 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -55,6 +55,39 @@ static GlobalValue::VisibilityTypes GetDecodedVisibility(unsigned Val) { } } +namespace { + /// @brief A class for maintaining the slot number definition + /// as a placeholder for the actual definition for forward constants defs. + class ConstantPlaceHolder : public ConstantExpr { + ConstantPlaceHolder(); // DO NOT IMPLEMENT + void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT +public: + Use Op; + ConstantPlaceHolder(const Type *Ty) + : ConstantExpr(Ty, Instruction::UserOp1, &Op, 1), + Op(UndefValue::get(Type::Int32Ty), this) { + } + }; +} + +Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, + const Type *Ty) { + if (Idx >= size()) { + // Insert a bunch of null values. + Uses.resize(Idx+1); + OperandList = &Uses[0]; + NumOperands = Idx+1; + } + + if (Uses[Idx]) + return cast<Constant>(getOperand(Idx)); + + // Create and return a placeholder, which will later be RAUW'd. + Constant *C = new ConstantPlaceHolder(Ty); + Uses[Idx].init(C, this); + return C; +} + const Type *BitcodeReader::getTypeByID(unsigned ID, bool isTypeTable) { // If the TypeID is in range, return it. @@ -324,6 +357,7 @@ bool BitcodeReader::ParseConstants(BitstreamReader &Stream) { // Read all the records for this value table. const Type *CurTy = Type::Int32Ty; + unsigned NextCstNo = ValueList.size(); while (1) { unsigned Code = Stream.ReadCode(); if (Code == bitc::END_BLOCK) { @@ -341,6 +375,9 @@ bool BitcodeReader::ParseConstants(BitstreamReader &Stream) { } } + if (NextCstNo != ValueList.size()) + return Error("Invalid constant reference!"); + return Stream.ReadBlockEnd(); } @@ -403,9 +440,48 @@ bool BitcodeReader::ParseConstants(BitstreamReader &Stream) { else V = UndefValue::get(CurTy); break; + + case bitc::CST_CODE_AGGREGATE: {// AGGREGATE: [n, n x value number] + if (Record.empty() || Record.size() < Record[0]+1) + return Error("Invalid CST_AGGREGATE record"); + + unsigned Size = Record[0]; + std::vector<Constant*> Elts; + + if (const StructType *STy = dyn_cast<StructType>(CurTy)) { + for (unsigned i = 0; i != Size; ++i) + Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], + STy->getElementType(i))); + V = ConstantStruct::get(STy, Elts); + } else if (const ArrayType *ATy = dyn_cast<ArrayType>(CurTy)) { + const Type *EltTy = ATy->getElementType(); + for (unsigned i = 0; i != Size; ++i) + Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], EltTy)); + V = ConstantArray::get(ATy, Elts); + } else if (const VectorType *VTy = dyn_cast<VectorType>(CurTy)) { + const Type *EltTy = VTy->getElementType(); + for (unsigned i = 0; i != Size; ++i) + Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], EltTy)); + V = ConstantVector::get(Elts); + } else { + V = UndefValue::get(CurTy); + } + } + } + + if (NextCstNo == ValueList.size()) + ValueList.push_back(V); + else if (ValueList[NextCstNo] == 0) + ValueList.initVal(NextCstNo, V); + else { + // If there was a forward reference to this constant, + Value *OldV = ValueList[NextCstNo]; + ValueList.setOperand(NextCstNo, V); + OldV->replaceAllUsesWith(V); + delete OldV; } - ValueList.push_back(V); + ++NextCstNo; } } |