15#include "mlir/IR/Block.h"
16#include "mlir/IR/Location.h"
19#include "llvm/Support/SaveAndRestore.h"
34 "__gxx_personality_sj0",
nullptr};
36 "__gxx_personality_seh0",
nullptr};
38 "objc_exception_throw"};
40 "__gnu_objc_personality_sj0",
"objc_exception_throw"};
42 "__gnu_objc_personality_seh0",
"objc_exception_throw"};
44 "__gnustep_objcxx_personality_v0",
nullptr};
46 "__gnustep_objc_personality_v0",
nullptr};
50 "__C_specific_handler",
nullptr};
52 "__CxxFrameHandler3",
nullptr};
54 "__gxx_wasm_personality_v0",
nullptr};
62 const llvm::Triple &triple = target.
getTriple();
63 if (triple.isWindowsMSVCEnvironment())
77 const llvm::Triple &triple = target.
getTriple();
78 if (triple.isWindowsMSVCEnvironment())
100 llvm_unreachable(
"bad runtime kind");
105 const llvm::Triple &triple = target.
getTriple();
106 if (triple.isWindowsMSVCEnvironment())
108 if (triple.isOSAIX())
126 if (target.
getTriple().isWindowsMSVCEnvironment())
152 llvm_unreachable(
"bad runtime kind");
156 return triple.getArch() == llvm::Triple::x86
186 return get(cgf.
cgm, dyn_cast_or_null<FunctionDecl>(fg));
192 mlir::Type i32Ty = cgm.
getBuilder().getI32Type();
193 auto funcTy = cir::FuncType::get({}, i32Ty,
true);
198 return personalityFn.getSymName();
203 if (
cgm.getLangOpts().OpenMPIsTargetDevice &&
204 (triple.isNVPTX() || triple.isAMDGCN())) {
205 cgm.errorNYI(
"emitCXXThrowExpr OpenMP with NVPTX or AMDGCN Triples");
210 QualType throwType = subExpr->getType();
212 cgm.errorNYI(
"emitCXXThrowExpr ObjCObjectPointerType");
216 cgm.getCXXABI().emitThrow(*
this, e);
220 cgm.getCXXABI().emitRethrow(*
this,
true);
260 QualType caughtType =
cgm.getASTContext().getUnqualifiedArrayType(
263 cgm.errorNYI(
"addCatchHandlerAttr: caughtType ObjCObjectPointerType");
269 handlerAttrs.push_back(typeInfo.
rtti);
272 handlerAttrs.push_back(cir::CatchAllAttr::get(&
getMLIRContext()));
277 if (
s.getTryBlock()->body_empty())
278 return mlir::LogicalResult::success();
280 mlir::Location loc =
getLoc(
s.getSourceRange());
283 mlir::OpBuilder::InsertPoint scopeIP;
284 cir::ScopeOp::create(
286 [&](mlir::OpBuilder &
b, mlir::Location loc) {
287 scopeIP = builder.saveInsertionPoint();
291 auto funcOp = mlir::cast<cir::FuncOp>(
curFn);
292 if (!funcOp.getPersonality())
295 mlir::OpBuilder::InsertionGuard guard(builder);
296 builder.restoreInsertionPoint(scopeIP);
301 const bool isTargetDevice =
302 (
cgm.getLangOpts().OpenMPIsTargetDevice && (t.isNVPTX() || t.isAMDGCN()));
303 if (isTargetDevice) {
304 cgm.errorNYI(
"emitCXXTryStmt: OpenMP target region offloaded to GPU");
305 return mlir::success();
308 mlir::Location tryLoc =
getLoc(
s.getBeginLoc());
312 builder.getInsertionBlock()};
315 cgm.errorNYI(
"enterCXXTryStmt: EHAsynch");
316 return mlir::failure();
320 mlir::LogicalResult tryRes = mlir::success();
321 auto tryOp = cir::TryOp::create(
324 [&](mlir::OpBuilder &
b, mlir::Location loc) {
329 if (
emitStmt(
s.getTryBlock(),
true).failed())
330 tryRes = mlir::failure();
332 cir::YieldOp::create(builder, loc);
335 [&](mlir::OpBuilder &
b, mlir::Location loc,
336 mlir::OperationState &result) {
337 mlir::OpBuilder::InsertionGuard guard(
b);
338 bool hasCatchAll =
false;
339 unsigned numHandlers =
s.getNumHandlers();
341 for (
unsigned i = 0; i != numHandlers; ++i) {
345 mlir::Region *region = result.addRegion();
346 builder.createBlock(region, {}, {ehTokenTy}, {loc});
351 mlir::Region *region = result.addRegion();
352 mlir::Block *unwindBlock =
353 builder.createBlock(region, {}, {ehTokenTy}, {loc});
354 cir::ResumeOp::create(builder, loc, unwindBlock->getArgument(0));
360 return mlir::failure();
363 tryOp.setHandlerTypesAttr(
369 unsigned numHandlers =
s.getNumHandlers();
370 for (
unsigned i = 0; i != numHandlers; ++i) {
372 mlir::Region *handler = &tryOp.getHandlerRegions()[i];
375 mlir::OpBuilder::InsertionGuard guard(builder);
376 builder.setInsertionPointToStart(&handler->front());
379 mlir::Value ehToken = handler->front().getArgument(0);
388 cgm.getCXXABI().emitBeginCatch(*
this, catchStmt, ehToken);
394 [[maybe_unused]] mlir::LogicalResult emitResult =
396 assert(emitResult.succeeded() &&
"failed to emit catch handler block");
408 mlir::Block *block = &handler->getBlocks().back();
409 if (block->empty() ||
410 !block->back().hasTrait<mlir::OpTrait::IsTerminator>()) {
411 mlir::OpBuilder::InsertionGuard guard(builder);
412 builder.setInsertionPointToEnd(block);
413 builder.createYield(handlerLoc);
417 return mlir::success();
430 if (!lo.Exceptions || lo.IgnoreExceptions) {
431 if (!lo.Borland && !lo.MicrosoftExt)
433 cgm.errorNYI(
"isInvokeDest: no exceptions or ignore exception");
438 if (lo.CUDA && lo.CUDAIsDevice)
441 return ehStack.requiresCatchOrCleanup();
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(ArrayRef< mlir::Value * > valuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
const clang::LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
void addCatchHandlerAttr(const CXXCatchStmt *catchStmt, SmallVector< mlir::Attribute > &handlerAttrs)
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::Operation * curFn
The current function or global initializer that is generated code for.
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
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()
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.
CIRGenBuilderTy & getBuilder()
const clang::TargetInfo & getTarget() const
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::NamedAttrList extraAttrs={}, bool isLocal=false, bool assumeConvergent=false)
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
CXXCatchStmt - This represents a C++ catch block.
SourceLocation getCatchLoc() const
Stmt * getHandlerBlock() const
SourceLocation getBeginLoc() const LLVM_READONLY
VarDecl * getExceptionDecl() const
QualType getCaughtType() 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.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
The collection of all-type qualifiers we support.
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.
static bool ehCleanupScope()
static bool currentFuncletPad()
static bool incrementProfileCounter()
Represents a scope, including function bodies, compound statements, and the substatements of if/while...
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
The exceptions personality for a function.
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