void TryCatchScope::emitCatchBodiesMSVC(IRState &irs, llvm::Value *) { assert(catchBlocks.empty()); auto &scopes = irs.funcGen().scopes; auto &PGO = irs.funcGen().pgo; auto catchSwitchBlock = irs.insertBBBefore(endbb, "catch.dispatch"); llvm::BasicBlock *unwindto = scopes.currentCleanupScope() > 0 ? scopes.getLandingPad() : nullptr; auto catchSwitchInst = llvm::CatchSwitchInst::Create( llvm::ConstantTokenNone::get(irs.context()), unwindto, stmt->catches->dim, "", catchSwitchBlock); for (auto c : *stmt->catches) { auto catchBB = irs.insertBBBefore(endbb, llvm::Twine("catch.") + c->type->toChars()); irs.scope() = IRScope(catchBB); irs.DBuilder.EmitBlockStart(c->loc); PGO.emitCounterIncrement(c); emitBeginCatchMSVC(irs, c, catchSwitchInst); // Emit handler, if there is one. The handler is zero, for instance, // when building 'catch { debug foo(); }' in non-debug mode. if (c->handler) Statement_toIR(c->handler, &irs); if (!irs.scopereturned()) irs.ir->CreateBr(endbb); irs.DBuilder.EmitBlockEnd(); } scopes.pushCleanup(catchSwitchBlock, catchSwitchBlock); // if no landing pad is created, the catch blocks are unused, but // the verifier complains if there are catchpads without personality // so we can just set it unconditionally if (!irs.func()->func->hasPersonalityFn()) { const char *personality = "__CxxFrameHandler3"; LLFunction *personalityFn = getRuntimeFunction(Loc(), irs.module, personality); irs.func()->func->setPersonalityFn(personalityFn); } }
void visit(LabelStatement *stmt) override { IF_LOG Logger::println("LabelStatement::toNakedIR(): %s", stmt->loc.toChars()); LOG_SCOPE; printLabelName(irs->nakedAsm, mangleExact(irs->func()->decl), stmt->ident->toChars()); irs->nakedAsm << ":"; if (stmt->statement) { stmt->statement->accept(this); } }