+void WinException::emitSEHActionsForRange(WinEHFuncInfo &FuncInfo,
+ MCSymbol *BeginLabel,
+ MCSymbol *EndLabel, int State) {
+ auto &OS = *Asm->OutStreamer;
+ MCContext &Ctx = Asm->OutContext;
+
+ assert(BeginLabel && EndLabel);
+ while (State != -1) {
+ // struct Entry {
+ // imagerel32 LabelStart;
+ // imagerel32 LabelEnd;
+ // imagerel32 FilterOrFinally; // One means catch-all.
+ // imagerel32 ExceptOrNull; // Zero means __finally.
+ // };
+ SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
+ const MCExpr *FilterOrFinally;
+ const MCExpr *ExceptOrNull;
+ auto *Handler = UME.Handler.get<MachineBasicBlock *>();
+ if (UME.IsFinally) {
+ FilterOrFinally = create32bitRef(getMCSymbolForMBBOrGV(Asm, Handler));
+ ExceptOrNull = MCConstantExpr::create(0, Ctx);
+ } else {
+ // For an except, the filter can be 1 (catch-all) or a function
+ // label.
+ FilterOrFinally = UME.Filter ? create32bitRef(UME.Filter)
+ : MCConstantExpr::create(1, Ctx);
+ ExceptOrNull = create32bitRef(Handler->getSymbol());
+ }
+
+ OS.EmitValue(getLabelPlusOne(BeginLabel), 4);
+ OS.EmitValue(getLabelPlusOne(EndLabel), 4);
+ OS.EmitValue(FilterOrFinally, 4);
+ OS.EmitValue(ExceptOrNull, 4);
+
+ assert(UME.ToState < State && "states should decrease");
+ State = UME.ToState;
+ }
+}
+