namespace llvm {
+class AsmPrinter;
class MachineBasicBlock;
class MachineFunction;
class MachineInstr;
class MCSymbol;
+typedef MCSymbol *ExceptionSymbolProvider(AsmPrinter *Asm);
+
/// \brief Collects and handles AsmPrinter objects required to build debug
/// or EH information.
class AsmPrinterHandler {
/// beginFunction at all.
virtual void endFunction(const MachineFunction *MF) = 0;
+ virtual void beginFragment(const MachineBasicBlock *MBB,
+ ExceptionSymbolProvider ESP) {}
+ virtual void endFragment() {}
+
/// \brief Emit target-specific EH funclet machinery.
virtual void beginFunclet(const MachineBasicBlock &MBB,
MCSymbol *Sym = nullptr) {}
: EHStreamer(A), shouldEmitCFI(false) {}
void DwarfCFIExceptionBase::markFunctionEnd() {
- if (shouldEmitCFI)
- Asm->OutStreamer->EmitCFIEndProc();
+ endFragment();
if (MMI->getLandingPads().empty())
return;
MMI->TidyLandingPads();
}
+void DwarfCFIExceptionBase::endFragment() {
+ if (shouldEmitCFI)
+ Asm->OutStreamer->EmitCFIEndProc();
+}
+
DwarfCFIException::DwarfCFIException(AsmPrinter *A)
: DwarfCFIExceptionBase(A), shouldEmitPersonality(false),
- shouldEmitLSDA(false), shouldEmitMoves(false),
- moveTypeModule(AsmPrinter::CFI_M_None) {}
+ shouldEmitLSDA(false), forceEmitPersonality(false),
+ shouldEmitMoves(false), moveTypeModule(AsmPrinter::CFI_M_None) {}
DwarfCFIException::~DwarfCFIException() {}
}
}
+static MCSymbol *getExceptionSym(AsmPrinter *Asm) {
+ return Asm->getCurExceptionSym();
+}
+
void DwarfCFIException::beginFunction(const MachineFunction *MF) {
shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
const Function *F = MF->getFunction();
Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
// Emit a personality function even when there are no landing pads
- bool forceEmitPersonality =
+ forceEmitPersonality =
// ...if a personality function is explicitly specified
F->hasPersonalityFn() &&
// ... and it's not known to be a noop in the absence of invokes
LSDAEncoding != dwarf::DW_EH_PE_omit;
shouldEmitCFI = shouldEmitPersonality || shouldEmitMoves;
+ beginFragment(&*MF->begin(), getExceptionSym);
+}
+
+void DwarfCFIException::beginFragment(const MachineBasicBlock *MBB,
+ ExceptionSymbolProvider ESP) {
if (!shouldEmitCFI)
return;
if (!shouldEmitPersonality)
return;
+ auto *F = MBB->getParent()->getFunction();
+ auto *P = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
+ assert(P && "Expected personality function");
+
// If we are forced to emit this personality, make sure to record
// it because it might not appear in any landingpad
if (forceEmitPersonality)
- MMI->addPersonality(Per);
+ MMI->addPersonality(P);
+ const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
+ unsigned PerEncoding = TLOF.getPersonalityEncoding();
const MCSymbol *Sym =
- TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
+ TLOF.getCFIPersonalitySymbol(P, *Asm->Mang, Asm->TM, MMI);
Asm->OutStreamer->EmitCFIPersonality(Sym, PerEncoding);
// Provide LSDA information.
- if (!shouldEmitLSDA)
- return;
-
- Asm->OutStreamer->EmitCFILsda(Asm->getCurExceptionSym(), LSDAEncoding);
+ if (shouldEmitLSDA)
+ Asm->OutStreamer->EmitCFILsda(ESP(Asm), TLOF.getLSDAEncoding());
}
/// endFunction - Gather and emit post-function exception information.
#include "EHStreamer.h"
#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/MC/MCDwarf.h"
namespace llvm {
class MachineFunction;
bool shouldEmitCFI;
void markFunctionEnd() override;
+ void endFragment() override;
};
class LLVM_LIBRARY_VISIBILITY DwarfCFIException : public DwarfCFIExceptionBase {
/// Per-function flag to indicate if .cfi_personality should be emitted.
bool shouldEmitPersonality;
+ /// Per-function flag to indicate if .cfi_personality must be emitted.
+ bool forceEmitPersonality;
+
/// Per-function flag to indicate if .cfi_lsda should be emitted.
bool shouldEmitLSDA;
/// Gather and emit post-function exception information.
void endFunction(const MachineFunction *) override;
+
+ void beginFragment(const MachineBasicBlock *MBB,
+ ExceptionSymbolProvider ESP) override;
};
class LLVM_LIBRARY_VISIBILITY ARMException : public DwarfCFIExceptionBase {