forked from OSchip/llvm-project
[WinEH] Fill out .xdata for catch objects
This add support for catching an exception such that an exception object available to the catch handler will be initialized by the runtime. llvm-svn: 234062
This commit is contained in:
parent
3337064a47
commit
69132a7fb2
|
@ -75,6 +75,7 @@ public:
|
|||
|
||||
void setExceptionVar(const Value *Val) { ExceptionObjectVar = Val; }
|
||||
void setExceptionVarIndex(int Index) { ExceptionObjectIndex = Index; }
|
||||
int getExceptionVarIndex() const { return ExceptionObjectIndex; }
|
||||
void setReturnTargets(TinyPtrVector<BasicBlock *> &Targets) {
|
||||
ReturnTargets = Targets;
|
||||
}
|
||||
|
@ -120,8 +121,7 @@ struct WinEHUnwindMapEntry {
|
|||
struct WinEHHandlerType {
|
||||
int Adjectives;
|
||||
GlobalVariable *TypeDescriptor;
|
||||
int CatchObjIdx;
|
||||
int CatchObjOffset;
|
||||
int CatchObjRecoverIdx;
|
||||
Function *Handler;
|
||||
};
|
||||
|
||||
|
|
|
@ -450,9 +450,16 @@ void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) {
|
|||
const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::Create(
|
||||
ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
|
||||
|
||||
MCSymbol *FrameAllocOffset =
|
||||
Asm->OutContext.getOrCreateFrameAllocSymbol(
|
||||
GlobalValue::getRealLinkageName(F->getName()),
|
||||
HT.CatchObjRecoverIdx);
|
||||
const MCSymbolRefExpr *FrameAllocOffsetRef = MCSymbolRefExpr::Create(
|
||||
FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
|
||||
|
||||
OS.EmitIntValue(HT.Adjectives, 4); // Adjectives
|
||||
OS.EmitValue(createImageRel32(HT.TypeDescriptor), 4); // Type
|
||||
OS.EmitIntValue(HT.CatchObjOffset, 4); // CatchObjOffset
|
||||
OS.EmitValue(FrameAllocOffsetRef, 4); // CatchObjOffset
|
||||
OS.EmitValue(createImageRel32(HT.Handler), 4); // Handler
|
||||
OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset
|
||||
}
|
||||
|
|
|
@ -321,9 +321,7 @@ void WinEHNumbering::createTryBlockMapEntry(int TryLow, int TryHigh,
|
|||
cast<GlobalVariable>(CS->getAggregateElement(1)->stripPointerCasts());
|
||||
}
|
||||
HT.Handler = cast<Function>(CH->getHandlerBlockOrFunc());
|
||||
// FIXME: We don't support catching objects yet!
|
||||
HT.CatchObjIdx = INT_MAX;
|
||||
HT.CatchObjOffset = 0;
|
||||
HT.CatchObjRecoverIdx = CH->getExceptionVarIndex();
|
||||
TBME.HandlerArray.push_back(HT);
|
||||
}
|
||||
FuncInfo.TryBlockMap.push_back(TBME);
|
||||
|
|
|
@ -5410,8 +5410,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
|||
"can only escape static allocas");
|
||||
int FI = FuncInfo.StaticAllocaMap[Slot];
|
||||
MCSymbol *FrameAllocSym =
|
||||
MF.getMMI().getContext().getOrCreateFrameAllocSymbol(MF.getName(),
|
||||
Idx);
|
||||
MF.getMMI().getContext().getOrCreateFrameAllocSymbol(
|
||||
GlobalValue::getRealLinkageName(MF.getName()), Idx);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, dl,
|
||||
TII->get(TargetOpcode::FRAME_ALLOC))
|
||||
.addSym(FrameAllocSym)
|
||||
|
@ -5431,8 +5431,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
|||
auto *Idx = cast<ConstantInt>(I.getArgOperand(2));
|
||||
unsigned IdxVal = unsigned(Idx->getLimitedValue(INT_MAX));
|
||||
MCSymbol *FrameAllocSym =
|
||||
MF.getMMI().getContext().getOrCreateFrameAllocSymbol(Fn->getName(),
|
||||
IdxVal);
|
||||
MF.getMMI().getContext().getOrCreateFrameAllocSymbol(
|
||||
GlobalValue::getRealLinkageName(Fn->getName()), IdxVal);
|
||||
|
||||
// Create a TargetExternalSymbol for the label to avoid any target lowering
|
||||
// that would make this PC relative.
|
||||
|
|
|
@ -1595,7 +1595,7 @@ CleanupHandler *WinEHPrepare::findCleanupHandler(BasicBlock *StartBB,
|
|||
// This is a public function, declared in WinEHFuncInfo.h and is also
|
||||
// referenced by WinEHNumbering in FunctionLoweringInfo.cpp.
|
||||
void llvm::parseEHActions(const IntrinsicInst *II,
|
||||
SmallVectorImpl<ActionHandler *> &Actions) {
|
||||
SmallVectorImpl<ActionHandler *> &Actions) {
|
||||
for (unsigned I = 0, E = II->getNumArgOperands(); I != E;) {
|
||||
uint64_t ActionKind =
|
||||
cast<ConstantInt>(II->getArgOperand(I))->getZExtValue();
|
||||
|
@ -1609,14 +1609,14 @@ void llvm::parseEHActions(const IntrinsicInst *II,
|
|||
CH->setHandlerBlockOrFunc(Handler);
|
||||
CH->setExceptionVarIndex(EHObjIndexVal);
|
||||
Actions.push_back(CH);
|
||||
}
|
||||
else {
|
||||
assert(ActionKind == 0 && "expected a cleanup or a catch action!");
|
||||
} else if (ActionKind == 0) {
|
||||
Constant *Handler = cast<Constant>(II->getArgOperand(I + 1));
|
||||
I += 2;
|
||||
auto *CH = new CleanupHandler(/*BB=*/nullptr);
|
||||
CH->setHandlerBlockOrFunc(Handler);
|
||||
Actions.push_back(CH);
|
||||
} else {
|
||||
llvm_unreachable("Expected either a catch or cleanup handler!");
|
||||
}
|
||||
}
|
||||
std::reverse(Actions.begin(), Actions.end());
|
||||
|
|
|
@ -148,13 +148,13 @@ try.cont8: ; preds = %lpad2, %try.cont
|
|||
; CHECK-NEXT:"$handlerMap$0$?f@@YAXXZ":
|
||||
; CHECK-NEXT: .long 8
|
||||
; CHECK-NEXT: .long "??_R0H@8"@IMGREL
|
||||
; CHECK-NEXT: .long 0
|
||||
; CHECK-NEXT: .long ".L?f@@YAXXZ$frame_escape_0"
|
||||
; CHECK-NEXT: .long "?f@@YAXXZ.catch"@IMGREL
|
||||
; CHECK-NEXT: .long ".L?f@@YAXXZ.catch$parent_frame_offset"
|
||||
; CHECK-NEXT:"$handlerMap$1$?f@@YAXXZ":
|
||||
; CHECK-NEXT: .long 0
|
||||
; CHECK-NEXT: .long "??_R0N@8"@IMGREL
|
||||
; CHECK-NEXT: .long 0
|
||||
; CHECK-NEXT: .long ".L?f@@YAXXZ$frame_escape_1"
|
||||
; CHECK-NEXT: .long "?f@@YAXXZ.catch1"@IMGREL
|
||||
; CHECK-NEXT: .long ".L?f@@YAXXZ.catch1$parent_frame_offset"
|
||||
; CHECK-NEXT:"$ip2state$?f@@YAXXZ":
|
||||
|
|
Loading…
Reference in New Issue