mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-11 21:24:33 +00:00
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241888 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -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) {
|
||||
|
Reference in New Issue
Block a user