18#include "llvm/Support/SaveAndRestore.h"
33 "__gxx_personality_sj0",
nullptr};
35 "__gxx_personality_seh0",
nullptr};
37 "objc_exception_throw"};
39 "__gnu_objc_personality_sj0",
"objc_exception_throw"};
41 "__gnu_objc_personality_seh0",
"objc_exception_throw"};
43 "__gnustep_objcxx_personality_v0",
nullptr};
45 "__gnustep_objc_personality_v0",
nullptr};
49 "__C_specific_handler",
nullptr};
51 "__CxxFrameHandler3",
nullptr};
53 "__gxx_wasm_personality_v0",
nullptr};
61 const llvm::Triple &triple = target.
getTriple();
62 if (triple.isWindowsMSVCEnvironment())
76 const llvm::Triple &triple = target.
getTriple();
77 if (triple.isWindowsMSVCEnvironment())
99 llvm_unreachable(
"bad runtime kind");
104 const llvm::Triple &triple = target.
getTriple();
105 if (triple.isWindowsMSVCEnvironment())
107 if (triple.isOSAIX())
125 if (target.
getTriple().isWindowsMSVCEnvironment())
151 llvm_unreachable(
"bad runtime kind");
155 return triple.getArch() == llvm::Triple::x86
185 return get(cgf.
cgm, dyn_cast_or_null<FunctionDecl>(fg));
191 mlir::Type i32Ty = cgm.
getBuilder().getI32Type();
192 auto funcTy = cir::FuncType::get({}, i32Ty,
true);
197 return personalityFn.getSymName();
202 if (
cgm.getLangOpts().OpenMPIsTargetDevice &&
203 (triple.isNVPTX() || triple.isAMDGCN())) {
204 cgm.errorNYI(
"emitCXXThrowExpr OpenMP with NVPTX or AMDGCN Triples");
209 QualType throwType = subExpr->getType();
211 cgm.errorNYI(
"emitCXXThrowExpr ObjCObjectPointerType");
215 cgm.getCXXABI().emitThrow(*
this, e);
219 cgm.getCXXABI().emitRethrow(*
this,
true);
248 if (
s.getTryBlock()->body_empty())
249 return mlir::LogicalResult::success();
251 mlir::Location loc =
getLoc(
s.getSourceRange());
254 mlir::OpBuilder::InsertPoint scopeIP;
255 cir::ScopeOp::create(
257 [&](mlir::OpBuilder &
b, mlir::Location loc) {
258 scopeIP = builder.saveInsertionPoint();
261 mlir::OpBuilder::InsertionGuard guard(builder);
262 builder.restoreInsertionPoint(scopeIP);
264 cir::YieldOp::create(builder, loc);
273 const bool isTargetDevice =
274 (
cgm.getLangOpts().OpenMPIsTargetDevice && (t.isNVPTX() || t.isAMDGCN()));
275 if (isTargetDevice) {
277 "emitCXXTryStmtUnderScope: OpenMP target region offloaded to GPU");
278 return mlir::success();
281 unsigned numHandlers =
s.getNumHandlers();
282 mlir::Location tryLoc =
getLoc(
s.getBeginLoc());
283 mlir::OpBuilder::InsertPoint beginInsertTryBody;
285 bool hasCatchAll =
false;
286 for (
unsigned i = 0; i != numHandlers; ++i) {
287 hasCatchAll |=
s.getHandler(i)->getExceptionDecl() ==
nullptr;
296 auto tryOp = cir::TryOp::create(
299 [&](mlir::OpBuilder &
b, mlir::Location loc) {
300 beginInsertTryBody = builder.saveInsertionPoint();
303 [&](mlir::OpBuilder &
b, mlir::Location loc,
304 mlir::OperationState &result) {
305 mlir::OpBuilder::InsertionGuard guard(
b);
309 unsigned numRegionsToCreate =
310 hasCatchAll ? numHandlers : numHandlers + 1;
312 for (
unsigned i = 0; i != numRegionsToCreate; ++i) {
313 mlir::Region *region = result.addRegion();
314 builder.createBlock(region);
320 mlir::Location loc = tryOp.getLoc();
321 mlir::OpBuilder::InsertionGuard guard(builder);
322 builder.restoreInsertionPoint(beginInsertTryBody);
324 builder.getInsertionBlock()};
333 mlir::OpBuilder::InsertionGuard guard(builder);
335 builder.getInsertionBlock()};
336 if (
emitStmt(
s.getTryBlock(),
true).failed())
337 return mlir::failure();
344 return mlir::success();
349 unsigned numHandlers =
s.getNumHandlers();
351 for (
unsigned i = 0; i != numHandlers; ++i) {
354 cgm.errorNYI(
"enterCXXTryStmt: CatchStmt with ExceptionDecl");
359 mlir::Region *handler = &tryOp.getHandlerRegions()[i];
360 catchScope->
setHandler(i,
cgm.getCXXABI().getCatchAllTypeInfo(), handler,
366 cgm.errorNYI(
"enterCXXTryStmt: EHAsynch");
373 unsigned numHandlers =
s.getNumHandlers();
385 for (mlir::Region &handlerRegion : tryOp.getHandlerRegions()) {
386 if (handlerRegion.empty())
389 for (mlir::Block &
b : handlerRegion.getBlocks())
390 eraseBlocks.push_back(&
b);
393 for (mlir::Block *
b : eraseBlocks)
396 tryOp.setHandlerTypesAttr({});
403 catchScope.
begin() + numHandlers);
409 bool doImplicitRethrow =
416 cgm.errorNYI(
"exitCXXTryStmt: WASM personality");
420 bool hasCatchAll =
false;
421 for (
auto &handler : llvm::reverse(handlers)) {
422 hasCatchAll |= handler.isCatchAll();
423 mlir::Region *catchRegion = handler.region;
426 mlir::OpBuilder::InsertionGuard guard(builder);
427 builder.setInsertionPointToStart(&catchRegion->front());
435 cgm.getCXXABI().emitBeginCatch(*
this, catchStmt);
441 [[maybe_unused]] mlir::LogicalResult emitResult =
443 assert(emitResult.succeeded() &&
"failed to emit catch handler block");
446 cir::YieldOp::create(builder, tryOp->getLoc());
457 if (doImplicitRethrow) {
458 cgm.errorNYI(
"exitCXXTryStmt: doImplicitRethrow");
471 cgm.errorNYI(
"exitCXXTryStmt: WASM personality without catch all");
478 assert(
ehStack.requiresCatchOrCleanup());
479 assert(!
cgm.getLangOpts().IgnoreExceptions &&
480 "LandingPad should not be emitted when -fignore-exceptions are in "
484 switch (innermostEHScope.
getKind()) {
486 cgm.errorNYI(
"populateCatchHandlers: terminate");
500 mlir::ArrayAttr handlerTypesAttr = tryOp.getHandlerTypesAttr();
501 if (!handlerTypesAttr || handlerTypesAttr.empty()) {
503 bool hasCatchAll =
false;
507 switch (i->getKind()) {
509 cgm.errorNYI(
"emitLandingPad: Cleanup");
513 cgm.errorNYI(
"emitLandingPad: Filter");
517 cgm.errorNYI(
"emitLandingPad: Terminate");
526 llvm::make_range(catchScope.
begin(), catchScope.
end())) {
527 assert(handler.type.flags == 0 &&
528 "landingpads do not support catch handler flags");
531 if (handler.isCatchAll()) {
532 assert(!hasCatchAll);
537 cgm.errorNYI(
"emitLandingPad: non catch-all");
546 handlerAttrs.push_back(cir::CatchAllAttr::get(&
getMLIRContext()));
548 cgm.errorNYI(
"emitLandingPad: non catch-all");
553 tryOp.setHandlerTypesAttr(
570 cgm.errorNYI(
"getEHDispatchBlock: usesFuncletPads");
578 mlir::Block *originalBlock =
nullptr;
579 if (mayThrow && tryOp) {
584 cgm.errorNYI(
"getEHDispatchBlock: mayThrow & tryOp");
599 cgm.errorNYI(
"getEHDispatchBlock: mayThrow non-catch all");
603 cgm.errorNYI(
"getEHDispatchBlock: mayThrow & cleanup");
607 cgm.errorNYI(
"getEHDispatchBlock: mayThrow & Filter");
611 cgm.errorNYI(
"getEHDispatchBlock: mayThrow & Terminate");
618 cgm.errorNYI(
"getEHDispatchBlock: originalBlock");
635 if (!lo.Exceptions || lo.IgnoreExceptions) {
636 if (!lo.Borland && !lo.MicrosoftExt)
638 cgm.errorNYI(
"isInvokeDest: no exceptions or ignore exception");
643 if (lo.CUDA && lo.CUDAIsDevice)
646 return ehStack.requiresCatchOrCleanup();
653 assert(
ehStack.requiresCatchOrCleanup());
659 auto funcOp = mlir::cast<cir::FuncOp>(
curFn);
660 if (!funcOp.getPersonality())
665 cgm.errorNYI(
"getInvokeDestImpl: usesFuncletPads");
static const EHPersonality & getCXXPersonality(const TargetInfo &target, const CodeGenOptions &cgOpts)
static const EHPersonality & getCPersonality(const TargetInfo &target, const CodeGenOptions &cgOpts)
static const EHPersonality & getObjCPersonality(const TargetInfo &target, const LangOptions &langOpts, const CodeGenOptions &cgOpts)
static llvm::StringRef getPersonalityFn(CIRGenModule &cgm, const EHPersonality &personality)
static const EHPersonality & getObjCXXPersonality(const TargetInfo &target, const LangOptions &langOpts, const CodeGenOptions &cgOpts)
Determines the personality function to use when both C++ and Objective-C exceptions are being caught.
static const EHPersonality & getSEHPersonalityMSVC(const llvm::Triple &triple)
__device__ __2f16 float __ockl_bool s
Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const
Return address with different element type, a bitcast pointer, and the same alignment.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void forceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
const clang::LangOptions & getLangOpts() const
void enterCXXTryStmt(const CXXTryStmt &s, cir::TryOp tryOp, bool isFnTryBlock=false)
void populateEHCatchRegions(EHScopeStack::stable_iterator scope, cir::TryOp tryOp)
void exitCXXTryStmt(const CXXTryStmt &s, bool isFnTryBlock=false)
const TargetInfo & getTarget() const
void emitAnyExprToExn(const Expr *e, Address addr)
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
void emitAnyExprToMem(const Expr *e, Address location, Qualifiers quals, bool isInitializer)
Emits the code necessary to evaluate an arbitrary expression into the given memory location.
mlir::LogicalResult emitCXXTryStmtUnderScope(const clang::CXXTryStmt &s)
mlir::Operation * curFn
The current function or global initializer that is generated code for.
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
void populateCatchHandlersIfRequired(cir::TryOp tryOp)
mlir::Type convertTypeForMem(QualType t)
const clang::Decl * curCodeDecl
This is the inner-most code context, which includes blocks.
mlir::MLIRContext & getMLIRContext()
mlir::LogicalResult emitCXXTryStmt(const clang::CXXTryStmt &s)
void emitCXXThrowExpr(const CXXThrowExpr *e)
bool isCatchOrCleanupRequired()
LexicalScope * curLexScope
void populateCatchHandlers(cir::TryOp tryOp)
mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})
This class organizes the cross-function state that is used while generating CIR code.
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::ArrayAttr={}, bool isLocal=false, bool assumeConvergent=false)
CIRGenBuilderTy & getBuilder()
const clang::TargetInfo & getTarget() const
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
A scope which attempts to handle some, possibly all, types of exceptions.
const Handler & getHandler(unsigned i) const
unsigned getNumHandlers() const
void setHandler(unsigned i, CatchTypeInfo type, mlir::Region *region, const CXXCatchStmt *stmt)
void clearHandlerBlocks()
A non-stable pointer into the scope stack.
A saved depth on the scope stack.
A protected scope for zero-cost EH handling.
void setMayThrow(bool mayThrow)
CXXCatchStmt - This represents a C++ catch block.
Stmt * getHandlerBlock() const
VarDecl * getExceptionDecl() const
A C++ throw-expression (C++ [except.throw]).
const Expr * getSubExpr() const
CXXTryStmt - A C++ try block, including all handlers.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
bool hasDWARFExceptions() const
bool hasWasmExceptions() const
bool hasSjLjExceptions() const
bool hasSEHExceptions() const
This represents one expression.
Represents a function declaration or definition.
bool usesSEHTry() const
Indicates the function uses __try.
const Decl * getDecl() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
const VersionTuple & getVersion() const
@ MacOSX
'macosx' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the non-fragile AB...
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
@ GNUstep
'gnustep' is the modern non-fragile GNUstep runtime.
@ ObjFW
'objfw' is the Objective-C runtime included in ObjFW
@ iOS
'ios' is the Apple-provided NeXT-derived runtime on iOS or the iOS simulator; it is always non-fragil...
@ GCC
'gcc' is the Objective-C runtime shipped with GCC, implementing a fragile Objective-C ABI
@ WatchOS
'watchos' is a variant of iOS for Apple's watchOS.
A (possibly-)qualified type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isObjCObjectPointerType() const
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
U cast(CodeGen::Address addr)
static bool ehCleanupScope()
static bool catchParamOp()
static bool currentFuncletPad()
static bool incrementProfileCounter()
Represents a scope, including function bodies, compound statements, and the substatements of if/while...
void setAsTry(cir::TryOp op)
The exceptions personality for a function.
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets?
static const EHPersonality XL_CPlusPlus
static const EHPersonality GNU_ObjC_SJLJ
static const EHPersonality ZOS_CPlusPlus
static const EHPersonality GNUstep_ObjC
const char * personalityFn
static const EHPersonality MSVC_CxxFrameHandler3
static const EHPersonality MSVC_C_specific_handler
static const EHPersonality GNU_CPlusPlus_SEH
static const EHPersonality GNU_ObjC
static const EHPersonality GNU_CPlusPlus_SJLJ
static const EHPersonality GNU_C_SJLJ
static const EHPersonality GNU_C
static const EHPersonality NeXT_ObjC
static const EHPersonality & get(CIRGenModule &cgm, const clang::FunctionDecl *fd)
static const EHPersonality GNU_CPlusPlus
static const EHPersonality GNU_ObjCXX
static const EHPersonality GNU_C_SEH
static const EHPersonality MSVC_except_handler
static const EHPersonality GNU_ObjC_SEH
static const EHPersonality GNU_Wasm_CPlusPlus