+ case bitc::FUNC_CODE_INST_CLEANUPRET: { // CLEANUPRET: [val] or [val,bb#]
+ if (Record.size() != 1 && Record.size() != 2)
+ return error("Invalid record");
+ unsigned Idx = 0;
+ Value *CleanupPad = getValue(Record, Idx++, NextValueNo,
+ Type::getTokenTy(Context), OC_CleanupPad);
+ if (!CleanupPad)
+ return error("Invalid record");
+ BasicBlock *UnwindDest = nullptr;
+ if (Record.size() == 2) {
+ UnwindDest = getBasicBlock(Record[Idx++]);
+ if (!UnwindDest)
+ return error("Invalid record");
+ }
+
+ I = CleanupReturnInst::Create(cast<CleanupPadInst>(CleanupPad),
+ UnwindDest);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_CATCHRET: { // CATCHRET: [val,bb#]
+ if (Record.size() != 2)
+ return error("Invalid record");
+ unsigned Idx = 0;
+ Value *CatchPad = getValue(Record, Idx++, NextValueNo,
+ Type::getTokenTy(Context), OC_CatchPad);
+ if (!CatchPad)
+ return error("Invalid record");
+ BasicBlock *BB = getBasicBlock(Record[Idx++]);
+ if (!BB)
+ return error("Invalid record");
+
+ I = CatchReturnInst::Create(cast<CatchPadInst>(CatchPad), BB);
+ InstructionList.push_back(I);
+ break;
+ }
+ case bitc::FUNC_CODE_INST_CATCHPAD: { // CATCHPAD: [bb#,bb#,num,(ty,val)*]
+ if (Record.size() < 3)
+ return error("Invalid record");
+ unsigned Idx = 0;
+ 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(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: [num,(ty,val)*]
+ if (Record.size() < 1)
+ return error("Invalid record");
+ unsigned Idx = 0;
+ 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(Context, 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_CLEANUPENDPAD: { // CLEANUPENDPADINST: [val] or [val,bb#]
+ if (Record.size() != 1 && Record.size() != 2)
+ return error("Invalid record");
+ unsigned Idx = 0;
+ Value *CleanupPad = getValue(Record, Idx++, NextValueNo,
+ Type::getTokenTy(Context), OC_CleanupPad);
+ if (!CleanupPad)
+ return error("Invalid record");
+
+ BasicBlock *BB = nullptr;
+ if (Record.size() == 2) {
+ BB = getBasicBlock(Record[Idx++]);
+ if (!BB)
+ return error("Invalid record");
+ }
+ I = CleanupEndPadInst::Create(cast<CleanupPadInst>(CleanupPad), BB);
+ InstructionList.push_back(I);
+ break;
+ }