for (const CallSiteEntry &CSE : CallSites) {
if (!CSE.LPad)
continue; // Ignore gaps.
- NumEntries += CSE.LPad->SEHHandlers.size();
+ for (int Selector : CSE.LPad->TypeIds) {
+ // Ignore C++ filter clauses in SEH.
+ // FIXME: Implement cleanup clauses.
+ if (isCatchEHSelector(Selector))
+ ++NumEntries;
+ }
}
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);
}
- // Emit an entry for each action.
- for (SEHHandler Handler : LPad->SEHHandlers) {
+ // 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;
+
Asm->OutStreamer.EmitValue(Begin, 4);
Asm->OutStreamer.EmitValue(End, 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);
+ 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);
}
}
}