diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-07-10 07:00:44 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-07-10 07:00:44 +0000 |
commit | ae2ffc8a8c825acf46f58f20dc7d0ae5fecbdd0b (patch) | |
tree | bba694cd7ab6a7a5eb4aca757ebfc3b38b1e949d /llvm/lib/Bitcode/Reader/BitcodeReader.cpp | |
parent | 83505347724a3eeb42f66a0b58fb8ff5c4c9ea4c (diff) | |
download | bcm5719-llvm-ae2ffc8a8c825acf46f58f20dc7d0ae5fecbdd0b.tar.gz bcm5719-llvm-ae2ffc8a8c825acf46f58f20dc7d0ae5fecbdd0b.zip |
New EH representation for MSVC compatibility
Summary:
This introduces new instructions neccessary to implement MSVC-compatible
exception handling support. Most of the middle-end and none of the
back-end haven't been audited or updated to take them into account.
Reviewers: rnk, JosephTremoulet, reames, nlewycky, rjmccall
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D11041
llvm-svn: 241888
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 563e201336a..f13fc0476eb 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3793,6 +3793,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_CATCHBLOCK: { // CATCHBLOCK: [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 = CatchBlockInst::Create(Ty, NormalBB, UnwindBB, Args); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_TERMINATEBLOCK: { // TERMINATEBLOCK: [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 = TerminateBlockInst::Create(Context, UnwindDest, Args); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_CLEANUPBLOCK: { // CLEANUPBLOCK: [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 = CleanupBlockInst::Create(Ty, Args); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_CATCHENDBLOCK: { // CATCHENDBLOCKINST: [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 = CatchEndBlockInst::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) { |