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()));
279 mlir::Location loc =
getLoc(
s.getSourceRange());
282 mlir::OpBuilder::InsertPoint scopeIP;
283 cir::ScopeOp::create(
285 [&](mlir::OpBuilder &
b, mlir::Location loc) {
286 scopeIP = builder.saveInsertionPoint();
290 auto funcOp = mlir::cast<cir::FuncOp>(
curFn);
291 if (!funcOp.getPersonality())
294 mlir::OpBuilder::InsertionGuard guard(builder);
295 builder.restoreInsertionPoint(scopeIP);
300 const bool isTargetDevice =
301 (
cgm.getLangOpts().OpenMPIsTargetDevice && (t.isNVPTX() || t.isAMDGCN()));
302 if (isTargetDevice) {
303 cgm.errorNYI(
"emitCXXTryStmt: OpenMP target region offloaded to GPU");
304 return mlir::success();
307 mlir::Location tryLoc =
getLoc(
s.getBeginLoc());
311 builder.getInsertionBlock()};
314 cgm.errorNYI(
"enterCXXTryStmt: EHAsynch");
315 return mlir::failure();
319 mlir::LogicalResult tryRes = mlir::success();
320 auto tryOp = cir::TryOp::create(
323 [&](mlir::OpBuilder &
b, mlir::Location loc) {
328 if (bodyCallback(*this).failed())
329 tryRes = mlir::failure();
331 cir::YieldOp::create(builder, loc);
334 [&](mlir::OpBuilder &
b, mlir::Location loc,
335 mlir::OperationState &result) {
336 mlir::OpBuilder::InsertionGuard guard(
b);
337 bool hasCatchAll =
false;
338 unsigned numHandlers =
s.getNumHandlers();
340 for (
unsigned i = 0; i != numHandlers; ++i) {
344 mlir::Region *region = result.addRegion();
345 builder.createBlock(region, {}, {ehTokenTy}, {loc});
350 mlir::Region *region = result.addRegion();
351 mlir::Block *unwindBlock =
352 builder.createBlock(region, {}, {ehTokenTy}, {loc});
353 cir::ResumeOp::create(builder, loc, unwindBlock->getArgument(0));
359 return mlir::failure();
362 tryOp.setHandlerTypesAttr(
368 unsigned numHandlers =
s.getNumHandlers();
369 for (
unsigned i = 0; i != numHandlers; ++i) {
371 mlir::Region *handler = &tryOp.getHandlerRegions()[i];
374 mlir::OpBuilder::InsertionGuard guard(builder);
375 builder.setInsertionPointToStart(&handler->front());
378 mlir::Value ehToken = handler->front().getArgument(0);
387 cgm.getCXXABI().emitBeginCatch(*
this, catchStmt, ehToken);
393 [[maybe_unused]] mlir::LogicalResult emitResult =
395 assert(emitResult.succeeded() &&
"failed to emit catch handler block");
407 mlir::Block *block = &handler->getBlocks().back();
408 if (block->empty() ||
409 !block->back().hasTrait<mlir::OpTrait::IsTerminator>()) {
410 mlir::OpBuilder::InsertionGuard guard(builder);
411 builder.setInsertionPointToEnd(block);
412 builder.createYield(handlerLoc);
416 return mlir::success();
420 if (
s.getTryBlock()->body_empty())
421 return mlir::LogicalResult::success();
428 return cgf.
emitStmt(
s.getTryBlock(),
true);
430 ~simpleTryBodyEmitter()
override =
default;
433 simpleTryBodyEmitter emitter{
s};
448 if (!lo.Exceptions || lo.IgnoreExceptions) {
449 if (!lo.Borland && !lo.MicrosoftExt)
451 cgm.errorNYI(
"isInvokeDest: no exceptions or ignore exception");
456 if (lo.CUDA && lo.CUDAIsDevice)
459 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)
mlir::LogicalResult emitCXXTryStmt(const clang::CXXTryStmt &s, cxxTryBodyEmitter &bodyCallback)
const clang::Decl * curCodeDecl
This is the inner-most code context, which includes blocks.
mlir::MLIRContext & getMLIRContext()
void emitCXXThrowExpr(const CXXThrowExpr *e)
bool isCatchOrCleanupRequired()
CIRGenFunction(CIRGenModule &cgm, CIRGenBuilderTy &builder, bool suppressNewContext=false)
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