+ // We need to figure out which funclet the callsite was in so that we may
+ // properly nest the callee.
+ Instruction *CallSiteEHPad = nullptr;
+ if (CalledPersonality && CallerPersonality) {
+ EHPersonality Personality = classifyEHPersonality(CalledPersonality);
+ if (isFuncletEHPersonality(Personality)) {
+ DenseMap<BasicBlock *, ColorVector> CallerBlockColors =
+ colorEHFunclets(*Caller);
+ ColorVector &CallSiteColors = CallerBlockColors[OrigBB];
+ size_t NumColors = CallSiteColors.size();
+ // There is no single parent, inlining will not succeed.
+ if (NumColors > 1)
+ return false;
+ if (NumColors == 1) {
+ BasicBlock *CallSiteFuncletBB = CallSiteColors.front();
+ if (CallSiteFuncletBB != Caller->begin()) {
+ CallSiteEHPad = CallSiteFuncletBB->getFirstNonPHI();
+ assert(CallSiteEHPad->isEHPad() && "Expected an EHPad!");
+ }
+ }
+
+ // OK, the inlining site is legal. What about the target function?
+
+ if (CallSiteEHPad) {
+ if (Personality == EHPersonality::MSVC_CXX) {
+ // The MSVC personality cannot tolerate catches getting inlined into
+ // cleanup funclets.
+ if (isa<CleanupPadInst>(CallSiteEHPad)) {
+ // Ok, the call site is within a cleanuppad. Let's check the callee
+ // for catchpads.
+ for (const BasicBlock &CalledBB : *CalledFunc) {
+ if (isa<CatchPadInst>(CalledBB.getFirstNonPHI()))
+ return false;
+ }
+ }
+ } else if (isAsynchronousEHPersonality(Personality)) {
+ // SEH is even less tolerant, there may not be any sort of exceptional
+ // funclet in the callee.
+ for (const BasicBlock &CalledBB : *CalledFunc) {
+ if (CalledBB.isEHPad())
+ return false;
+ }
+ }
+ }
+ }
+ }
+