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));
190 if (
cgm.getLangOpts().OpenMPIsTargetDevice &&
191 (triple.isNVPTX() || triple.isAMDGCN())) {
192 cgm.errorNYI(
"emitCXXThrowExpr OpenMP with NVPTX or AMDGCN Triples");
197 QualType throwType = subExpr->getType();
199 cgm.errorNYI(
"emitCXXThrowExpr ObjCObjectPointerType");
203 cgm.getCXXABI().emitThrow(*
this, e);
207 cgm.getCXXABI().emitRethrow(*
this,
true);
236 if (
s.getTryBlock()->body_empty())
237 return mlir::LogicalResult::success();
239 mlir::Location loc =
getLoc(
s.getSourceRange());
242 mlir::OpBuilder::InsertPoint scopeIP;
243 cir::ScopeOp::create(
245 [&](mlir::OpBuilder &
b, mlir::Location loc) {
246 scopeIP = builder.saveInsertionPoint();
249 mlir::OpBuilder::InsertionGuard guard(builder);
250 builder.restoreInsertionPoint(scopeIP);
252 cir::YieldOp::create(builder, loc);
261 const bool isTargetDevice =
262 (
cgm.getLangOpts().OpenMPIsTargetDevice && (t.isNVPTX() || t.isAMDGCN()));
263 if (isTargetDevice) {
265 "emitCXXTryStmtUnderScope: OpenMP target region offloaded to GPU");
266 return mlir::success();
269 unsigned numHandlers =
s.getNumHandlers();
270 mlir::Location tryLoc =
getLoc(
s.getBeginLoc());
271 mlir::OpBuilder::InsertPoint beginInsertTryBody;
273 bool hasCatchAll =
false;
274 for (
unsigned i = 0; i != numHandlers; ++i) {
275 hasCatchAll |=
s.getHandler(i)->getExceptionDecl() ==
nullptr;
284 auto tryOp = cir::TryOp::create(
287 [&](mlir::OpBuilder &
b, mlir::Location loc) {
288 beginInsertTryBody = builder.saveInsertionPoint();
291 [&](mlir::OpBuilder &
b, mlir::Location loc,
292 mlir::OperationState &result) {
293 mlir::OpBuilder::InsertionGuard guard(
b);
297 unsigned numRegionsToCreate =
298 hasCatchAll ? numHandlers : numHandlers + 1;
300 for (
unsigned i = 0; i != numRegionsToCreate; ++i) {
301 mlir::Region *region = result.addRegion();
302 builder.createBlock(region);
308 mlir::Location loc = tryOp.getLoc();
309 mlir::OpBuilder::InsertionGuard guard(builder);
310 builder.restoreInsertionPoint(beginInsertTryBody);
312 builder.getInsertionBlock()};
321 mlir::OpBuilder::InsertionGuard guard(builder);
323 builder.getInsertionBlock()};
324 if (
emitStmt(
s.getTryBlock(),
true).failed())
325 return mlir::failure();
332 return mlir::success();
337 unsigned numHandlers =
s.getNumHandlers();
339 for (
unsigned i = 0; i != numHandlers; ++i) {
342 cgm.errorNYI(
"enterCXXTryStmt: CatchStmt with ExceptionDecl");
347 mlir::Region *handler = &tryOp.getHandlerRegions()[i];
348 catchScope->
setHandler(i,
cgm.getCXXABI().getCatchAllTypeInfo(), handler,
354 cgm.errorNYI(
"enterCXXTryStmt: EHAsynch");
361 unsigned numHandlers =
s.getNumHandlers();
373 for (mlir::Region &handlerRegion : tryOp.getHandlerRegions()) {
374 if (handlerRegion.empty())
377 for (mlir::Block &
b : handlerRegion.getBlocks())
378 eraseBlocks.push_back(&
b);
381 for (mlir::Block *
b : eraseBlocks)
384 tryOp.setHandlerTypesAttr({});
391 catchScope.
begin() + numHandlers);
397 bool doImplicitRethrow =
404 cgm.errorNYI(
"exitCXXTryStmt: WASM personality");
408 bool hasCatchAll =
false;
409 for (
auto &handler : llvm::reverse(handlers)) {
410 hasCatchAll |= handler.isCatchAll();
411 mlir::Region *catchRegion = handler.region;
414 mlir::OpBuilder::InsertionGuard guard(builder);
415 builder.setInsertionPointToStart(&catchRegion->front());
428 [[maybe_unused]] mlir::LogicalResult emitResult =
430 assert(emitResult.succeeded() &&
"failed to emit catch handler block");
433 cir::YieldOp::create(builder, tryOp->getLoc());
444 if (doImplicitRethrow) {
445 cgm.errorNYI(
"exitCXXTryStmt: doImplicitRethrow");
458 cgm.errorNYI(
"exitCXXTryStmt: WASM personality without catch all");
465 assert(
ehStack.requiresCatchOrCleanup());
466 assert(!
cgm.getLangOpts().IgnoreExceptions &&
467 "LandingPad should not be emitted when -fignore-exceptions are in "
471 switch (innermostEHScope.
getKind()) {
473 cgm.errorNYI(
"populateCatchHandlers: terminate");
487 mlir::ArrayAttr handlerTypesAttr = tryOp.getHandlerTypesAttr();
488 if (!handlerTypesAttr || handlerTypesAttr.empty()) {
490 bool hasCatchAll =
false;
494 switch (i->getKind()) {
496 cgm.errorNYI(
"emitLandingPad: Cleanup");
500 cgm.errorNYI(
"emitLandingPad: Filter");
504 cgm.errorNYI(
"emitLandingPad: Terminate");
513 llvm::make_range(catchScope.
begin(), catchScope.
end())) {
514 assert(handler.type.flags == 0 &&
515 "landingpads do not support catch handler flags");
518 if (handler.isCatchAll()) {
519 assert(!hasCatchAll);
524 cgm.errorNYI(
"emitLandingPad: non catch-all");
533 handlerAttrs.push_back(cir::CatchAllAttr::get(&
getMLIRContext()));
535 cgm.errorNYI(
"emitLandingPad: non catch-all");
540 tryOp.setHandlerTypesAttr(
557 cgm.errorNYI(
"getEHDispatchBlock: usesFuncletPads");
565 mlir::Block *originalBlock =
nullptr;
566 if (mayThrow && tryOp) {
571 cgm.errorNYI(
"getEHDispatchBlock: mayThrow & tryOp");
586 cgm.errorNYI(
"getEHDispatchBlock: mayThrow non-catch all");
590 cgm.errorNYI(
"getEHDispatchBlock: mayThrow & cleanup");
594 cgm.errorNYI(
"getEHDispatchBlock: mayThrow & Filter");
598 cgm.errorNYI(
"getEHDispatchBlock: mayThrow & Terminate");
605 cgm.errorNYI(
"getEHDispatchBlock: originalBlock");
622 if (!lo.Exceptions || lo.IgnoreExceptions) {
623 if (!lo.Borland && !lo.MicrosoftExt)
625 cgm.errorNYI(
"isInvokeDest: no exceptions or ignore exception");
630 if (lo.CUDA && lo.CUDAIsDevice)
633 return ehStack.requiresCatchOrCleanup();
640 assert(
ehStack.requiresCatchOrCleanup());
648 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 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)
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.
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 incrementProfileCounter()
static bool setFunctionPersonality()
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
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