MSVC_X86SEH,
MSVC_Win64SEH,
MSVC_CXX,
+ CoreCLR
};
/// \brief See if the given exception handling personality function is one
llvm_unreachable("invalid enum");
}
- /// \brief Returns true if this is an MSVC personality function.
- inline bool isMSVCEHPersonality(EHPersonality Pers) {
- // The two SEH personality functions can catch asynch exceptions. We assume
- // unknown personalities don't catch asynch exceptions.
+ /// \brief Returns true if this is a personality function that invokes
+ /// handler funclets (which must return to it).
+ inline bool isFuncletEHPersonality(EHPersonality Pers) {
switch (Pers) {
case EHPersonality::MSVC_CXX:
case EHPersonality::MSVC_X86SEH:
case EHPersonality::MSVC_Win64SEH:
+ case EHPersonality::CoreCLR:
return true;
default: return false;
}
.Case("_except_handler4", EHPersonality::MSVC_X86SEH)
.Case("__C_specific_handler", EHPersonality::MSVC_Win64SEH)
.Case("__CxxFrameHandler3", EHPersonality::MSVC_CXX)
+ .Case("ProcessCLRException", EHPersonality::CoreCLR)
.Default(EHPersonality::Unknown);
}
if (F->hasPersonalityFn())
Per = classifyEHPersonality(F->getPersonalityFn());
- // 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))
+ // Get rid of any dead landing pads if we're not using funclets. In funclet
+ // schemes, the landing pad is not actually reachable. It only exists so
+ // that we can emit the right table data.
+ if (!isFuncletEHPersonality(Per))
MMI->TidyLandingPads();
endFunclet();
if (Resumes.empty())
return false;
- // Check the personality, don't do anything if it's for MSVC.
+ // Check the personality, don't do anything if it's funclet-based.
EHPersonality Pers = classifyEHPersonality(Fn.getPersonalityFn());
- if (isMSVCEHPersonality(Pers))
+ if (isFuncletEHPersonality(Pers))
return false;
LLVMContext &Ctx = Fn.getContext();
LPads.push_back(LPI);
}
- // If this is an MSVC EH personality, we need to do a bit more work.
+ // If this personality uses funclets, we need to do a bit more work.
if (!Fn->hasPersonalityFn())
return;
EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn());
- if (!isMSVCEHPersonality(Personality))
+ if (!isFuncletEHPersonality(Personality))
return;
if (Personality == EHPersonality::MSVC_Win64SEH ||
findUnwindDestinations(FunctionLoweringInfo &FuncInfo,
const BasicBlock *EHPadBB,
SmallVectorImpl<MachineBasicBlock *> &UnwindDests) {
- bool IsMSVCCXX = classifyEHPersonality(FuncInfo.Fn->getPersonalityFn()) ==
- EHPersonality::MSVC_CXX;
+ EHPersonality Personality =
+ classifyEHPersonality(FuncInfo.Fn->getPersonalityFn());
+ bool IsMSVCCXX = Personality == EHPersonality::MSVC_CXX;
+ bool IsCoreCLR = Personality == EHPersonality::CoreCLR;
while (EHPadBB) {
const Instruction *Pad = EHPadBB->getFirstNonPHI();
if (isa<LandingPadInst>(Pad)) {
} else if (const auto *CPI = dyn_cast<CatchPadInst>(Pad)) {
// Add the catchpad handler to the possible destinations.
UnwindDests.push_back(FuncInfo.MBBMap[CPI->getNormalDest()]);
- // In MSVC C++, catchblocks are funclets and need prologues.
- if (IsMSVCCXX)
+ // In MSVC C++ and CoreCLR, catchblocks are funclets and need prologues.
+ if (IsMSVCCXX || IsCoreCLR)
UnwindDests.back()->setIsEHFuncletEntry();
EHPadBB = CPI->getUnwindDest();
} else if (const auto *CEPI = dyn_cast<CatchEndPadInst>(Pad)) {
BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(), II)
.addSym(Label);
- // If this is an MSVC-style personality function, we need to split the landing
+ // If this personality function uses funclets, we need to split the landing
// pad into several BBs.
const BasicBlock *LLVMBB = MBB->getBasicBlock();
const Constant *Personality = MF->getFunction()->getPersonalityFn();
MF->getMMI().addPersonality(PF);
EHPersonality PersonalityType = classifyEHPersonality(Personality);
- if (isMSVCEHPersonality(PersonalityType)) {
+ if (isFuncletEHPersonality(PersonalityType)) {
SmallVector<MachineBasicBlock *, 4> ClauseBBs;
const IntrinsicInst *ActionsCall =
dyn_cast<IntrinsicInst>(LLVMBB->getFirstInsertionPt());
// Classify the personality to see what kind of preparation we need.
Personality = classifyEHPersonality(Fn.getPersonalityFn());
- // Do nothing if this is not an MSVC personality.
- if (!isMSVCEHPersonality(Personality))
+ // Do nothing if this is not a funclet-based personality.
+ if (!isFuncletEHPersonality(Personality))
return false;
SmallVector<LandingPadInst *, 4> LPads;
const uint32_t *Mask = RegInfo->getCallPreservedMask(MF, CallConv);
assert(Mask && "Missing call preserved mask for calling convention");
- // If this is an invoke in a 32-bit function using an MSVC personality, assume
- // the function clobbers all registers. If an exception is thrown, the runtime
- // will not restore CSRs.
+ // If this is an invoke in a 32-bit function using a funclet-based
+ // personality, assume the function clobbers all registers. If an exception
+ // is thrown, the runtime will not restore CSRs.
// FIXME: Model this more precisely so that we can register allocate across
// the normal edge and spill and fill across the exceptional edge.
if (!Is64Bit && CLI.CS && CLI.CS->isInvoke()) {
CallerFn->hasPersonalityFn()
? classifyEHPersonality(CallerFn->getPersonalityFn())
: EHPersonality::Unknown;
- if (isMSVCEHPersonality(Pers))
+ if (isFuncletEHPersonality(Pers))
Mask = RegInfo->getNoPreservedMask();
}
if (WinEHParentName != F.getName() && !WinEHParentName.empty())
return false;
- // Check the personality. Do nothing if this is not an MSVC personality.
+ // Check the personality. Do nothing if this personality doesn't use funclets.
if (!F.hasPersonalityFn())
return false;
PersonalityFn =
if (!PersonalityFn)
return false;
Personality = classifyEHPersonality(PersonalityFn);
- if (!isMSVCEHPersonality(Personality))
+ if (!isFuncletEHPersonality(Personality))
return false;
// Skip this function if there are no EH pads and we aren't using IR-level
case EHPersonality::MSVC_X86SEH:
case EHPersonality::MSVC_Win64SEH:
case EHPersonality::MSVC_CXX:
+ case EHPersonality::CoreCLR:
return TypeInfo->isNullValue();
}
llvm_unreachable("invalid enum");