if (!shouldEmitPersonality && !shouldEmitMoves)
return;
- // Map all labels and get rid of any dead landing pads.
- MMI->TidyLandingPads();
+ EHPersonality Per = MMI->getPersonalityType();
+
+ // Get rid of any dead landing pads if we're not using a Windows EH scheme. In
+ // Windows EH schemes, the landing pad is not actually reachable. It only
+ // exists so that we can emit the right table data.
+ if (!isMSVCEHPersonality(Per))
+ MMI->TidyLandingPads();
if (shouldEmitPersonality) {
Asm->OutStreamer.PushSection();
// Emit the tables appropriate to the personality function in use. If we
// don't recognize the personality, assume it uses an Itanium-style LSDA.
- EHPersonality Per = MMI->getPersonalityType();
if (Per == EHPersonality::MSVC_Win64SEH)
emitCSpecificHandlerTable();
else if (Per == EHPersonality::MSVC_CXX)
for (const CallSiteEntry &CSE : CallSites) {
if (!CSE.LPad)
continue; // Ignore gaps.
- for (int Selector : CSE.LPad->TypeIds) {
- // Ignore C++ filter clauses in SEH.
- // FIXME: Implement cleanup clauses.
- if (isCatchEHSelector(Selector))
- ++NumEntries;
- }
+ NumEntries += CSE.LPad->SEHHandlers.size();
}
Asm->OutStreamer.EmitIntValue(NumEntries, 4);
+ // If there are no actions, we don't need to iterate again.
+ if (NumEntries == 0)
+ return;
+
// Emit the four-label records for each call site entry. The table has to be
// sorted in layout order, and the call sites should already be sorted.
for (const CallSiteEntry &CSE : CallSites) {
End = createImageRel32(EHFuncEndSym);
}
- // These aren't really type info globals, they are actually pointers to
- // filter functions ordered by selector. The zero selector is used for
- // cleanups, so slot zero corresponds to selector 1.
- const std::vector<const GlobalValue *> &SelectorToFilter = MMI->getTypeInfos();
-
- // Do a parallel iteration across typeids and clause labels, skipping filter
- // clauses.
- size_t NextClauseLabel = 0;
- for (size_t I = 0, E = LPad->TypeIds.size(); I < E; ++I) {
- // AddLandingPadInfo stores the clauses in reverse, but there is a FIXME
- // to change that.
- int Selector = LPad->TypeIds[E - I - 1];
-
- // Ignore C++ filter clauses in SEH.
- // FIXME: Implement cleanup clauses.
- if (!isCatchEHSelector(Selector))
- continue;
-
+ // Emit an entry for each action.
+ for (SEHHandler Handler : LPad->SEHHandlers) {
Asm->OutStreamer.EmitValue(Begin, 4);
Asm->OutStreamer.EmitValue(End, 4);
- if (isCatchEHSelector(Selector)) {
- assert(unsigned(Selector - 1) < SelectorToFilter.size());
- const GlobalValue *TI = SelectorToFilter[Selector - 1];
- if (TI) // Emit the filter function pointer.
- Asm->OutStreamer.EmitValue(createImageRel32(Asm->getSymbol(TI)), 4);
- else // Otherwise, this is a "catch i8* null", or catch all.
- Asm->OutStreamer.EmitIntValue(1, 4);
- }
- MCSymbol *ClauseLabel = LPad->ClauseLabels[NextClauseLabel++];
- Asm->OutStreamer.EmitValue(createImageRel32(ClauseLabel), 4);
+
+ // Emit the filter or finally function pointer, if present. Otherwise,
+ // emit '1' to indicate a catch-all.
+ const Function *F = Handler.FilterOrFinally;
+ if (F)
+ Asm->OutStreamer.EmitValue(createImageRel32(Asm->getSymbol(F)), 4);
+ else
+ Asm->OutStreamer.EmitIntValue(1, 4);
+
+ // Emit the recovery address, if present. Otherwise, this must be a
+ // finally.
+ const BlockAddress *BA = Handler.RecoverBA;
+ if (BA)
+ Asm->OutStreamer.EmitValue(
+ createImageRel32(Asm->GetBlockAddressSymbol(BA)), 4);
+ else
+ Asm->OutStreamer.EmitIntValue(0, 4);
}
}
}
std::max(CatchHigh, FuncInfo.CatchHandlerMaxState[HT.Handler]);
assert(TBME.TryLow <= TBME.TryHigh);
- assert(CatchHigh > TBME.TryHigh);
OS.EmitIntValue(TBME.TryLow, 4); // TryLow
OS.EmitIntValue(TBME.TryHigh, 4); // TryHigh
OS.EmitIntValue(CatchHigh, 4); // CatchHigh
if (HT.CatchObjRecoverIdx >= 0) {
MCSymbol *FrameAllocOffset =
Asm->OutContext.getOrCreateFrameAllocSymbol(
- GlobalValue::getRealLinkageName(F->getName()),
+ GlobalValue::getRealLinkageName(ParentF->getName()),
HT.CatchObjRecoverIdx);
FrameAllocOffsetRef = MCSymbolRefExpr::Create(
FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);