diff options
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 128 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 58 |
2 files changed, 186 insertions, 0 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index de91150c424..fea4c167ae3 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3811,6 +3811,134 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) { } break; } + // CLEANUPRET: [] or [ty,val] or [bb#] or [ty,val,bb#] + case bitc::FUNC_CODE_INST_CLEANUPRET: { + if (Record.size() < 2) + return error("Invalid record"); + unsigned Idx = 0; + bool HasReturnValue = !!Record[Idx++]; + bool HasUnwindDest = !!Record[Idx++]; + Value *RetVal = nullptr; + BasicBlock *UnwindDest = nullptr; + + if (HasReturnValue && getValueTypePair(Record, Idx, NextValueNo, RetVal)) + return error("Invalid record"); + if (HasUnwindDest) { + if (Idx == Record.size()) + return error("Invalid record"); + UnwindDest = getBasicBlock(Record[Idx++]); + if (!UnwindDest) + return error("Invalid record"); + } + + if (Record.size() != Idx) + return error("Invalid record"); + + I = CleanupReturnInst::Create(Context, RetVal, UnwindDest); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_CATCHRET: { // CATCHRET: [bb#] + if (Record.size() != 1) + return error("Invalid record"); + BasicBlock *BB = getBasicBlock(Record[0]); + if (!BB) + return error("Invalid record"); + I = CatchReturnInst::Create(BB); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_CATCHPAD: { // CATCHPAD: [ty,bb#,bb#,num,(ty,val)*] + if (Record.size() < 4) + return error("Invalid record"); + unsigned Idx = 0; + Type *Ty = getTypeByID(Record[Idx++]); + if (!Ty) + return error("Invalid record"); + BasicBlock *NormalBB = getBasicBlock(Record[Idx++]); + if (!NormalBB) + return error("Invalid record"); + BasicBlock *UnwindBB = getBasicBlock(Record[Idx++]); + if (!UnwindBB) + return error("Invalid record"); + unsigned NumArgOperands = Record[Idx++]; + SmallVector<Value *, 2> Args; + for (unsigned Op = 0; Op != NumArgOperands; ++Op) { + Value *Val; + if (getValueTypePair(Record, Idx, NextValueNo, Val)) + return error("Invalid record"); + Args.push_back(Val); + } + if (Record.size() != Idx) + return error("Invalid record"); + + I = CatchPadInst::Create(Ty, NormalBB, UnwindBB, Args); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_TERMINATEPAD: { // TERMINATEPAD: [bb#,num,(ty,val)*] + if (Record.size() < 1) + return error("Invalid record"); + unsigned Idx = 0; + bool HasUnwindDest = !!Record[Idx++]; + BasicBlock *UnwindDest = nullptr; + if (HasUnwindDest) { + if (Idx == Record.size()) + return error("Invalid record"); + UnwindDest = getBasicBlock(Record[Idx++]); + if (!UnwindDest) + return error("Invalid record"); + } + unsigned NumArgOperands = Record[Idx++]; + SmallVector<Value *, 2> Args; + for (unsigned Op = 0; Op != NumArgOperands; ++Op) { + Value *Val; + if (getValueTypePair(Record, Idx, NextValueNo, Val)) + return error("Invalid record"); + Args.push_back(Val); + } + if (Record.size() != Idx) + return error("Invalid record"); + + I = TerminatePadInst::Create(Context, UnwindDest, Args); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_CLEANUPPAD: { // CLEANUPPAD: [ty, num,(ty,val)*] + if (Record.size() < 2) + return error("Invalid record"); + unsigned Idx = 0; + Type *Ty = getTypeByID(Record[Idx++]); + if (!Ty) + return error("Invalid record"); + unsigned NumArgOperands = Record[Idx++]; + SmallVector<Value *, 2> Args; + for (unsigned Op = 0; Op != NumArgOperands; ++Op) { + Value *Val; + if (getValueTypePair(Record, Idx, NextValueNo, Val)) + return error("Invalid record"); + Args.push_back(Val); + } + if (Record.size() != Idx) + return error("Invalid record"); + + I = CleanupPadInst::Create(Ty, Args); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_CATCHENDPAD: { // CATCHENDPADINST: [bb#] or [] + if (Record.size() > 1) + return error("Invalid record"); + BasicBlock *BB = nullptr; + if (Record.size() == 1) { + BB = getBasicBlock(Record[0]); + if (!BB) + return error("Invalid record"); + } + I = CatchEndPadInst::Create(Context, BB); + InstructionList.push_back(I); + break; + } case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...] // Check magic if ((Record[0] >> 16) == SWITCH_INST_MAGIC) { diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 31ae0141ef8..20e31d1a102 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1851,6 +1851,64 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Code = bitc::FUNC_CODE_INST_RESUME; PushValueAndType(I.getOperand(0), InstID, Vals, VE); break; + case Instruction::CleanupRet: { + Code = bitc::FUNC_CODE_INST_CLEANUPRET; + const auto &CRI = cast<CleanupReturnInst>(I); + Vals.push_back(CRI.hasReturnValue()); + Vals.push_back(CRI.hasUnwindDest()); + if (CRI.hasReturnValue()) + PushValueAndType(CRI.getReturnValue(), InstID, Vals, VE); + if (CRI.hasUnwindDest()) + Vals.push_back(VE.getValueID(CRI.getUnwindDest())); + break; + } + case Instruction::CatchRet: { + Code = bitc::FUNC_CODE_INST_CATCHRET; + const auto &CRI = cast<CatchReturnInst>(I); + Vals.push_back(VE.getValueID(CRI.getSuccessor())); + break; + } + case Instruction::CatchPad: { + Code = bitc::FUNC_CODE_INST_CATCHPAD; + const auto &CPI = cast<CatchPadInst>(I); + Vals.push_back(VE.getTypeID(CPI.getType())); + Vals.push_back(VE.getValueID(CPI.getNormalDest())); + Vals.push_back(VE.getValueID(CPI.getUnwindDest())); + unsigned NumArgOperands = CPI.getNumArgOperands(); + Vals.push_back(NumArgOperands); + for (unsigned Op = 0; Op != NumArgOperands; ++Op) + PushValueAndType(CPI.getArgOperand(Op), InstID, Vals, VE); + break; + } + case Instruction::TerminatePad: { + Code = bitc::FUNC_CODE_INST_TERMINATEPAD; + const auto &TPI = cast<TerminatePadInst>(I); + Vals.push_back(TPI.hasUnwindDest()); + if (TPI.hasUnwindDest()) + Vals.push_back(VE.getValueID(TPI.getUnwindDest())); + unsigned NumArgOperands = TPI.getNumArgOperands(); + Vals.push_back(NumArgOperands); + for (unsigned Op = 0; Op != NumArgOperands; ++Op) + PushValueAndType(TPI.getArgOperand(Op), InstID, Vals, VE); + break; + } + case Instruction::CleanupPad: { + Code = bitc::FUNC_CODE_INST_CLEANUPPAD; + const auto &CPI = cast<CleanupPadInst>(I); + Vals.push_back(VE.getTypeID(CPI.getType())); + unsigned NumOperands = CPI.getNumOperands(); + Vals.push_back(NumOperands); + for (unsigned Op = 0; Op != NumOperands; ++Op) + PushValueAndType(CPI.getOperand(Op), InstID, Vals, VE); + break; + } + case Instruction::CatchEndPad: { + Code = bitc::FUNC_CODE_INST_CATCHENDPAD; + const auto &CEPI = cast<CatchEndPadInst>(I); + if (CEPI.hasUnwindDest()) + Vals.push_back(VE.getValueID(CEPI.getUnwindDest())); + break; + } case Instruction::Unreachable: Code = bitc::FUNC_CODE_INST_UNREACHABLE; AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV; |