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()));
278 CallEndCatch(mlir::Value catchToken) : catchToken(catchToken) {}
279 mlir::Value catchToken;
289 mlir::Type exnPtrTy) {
290 auto catchTokenTy = cir::CatchTokenType::get(cgf.
getBuilder().getContext());
291 auto beginCatch = cir::BeginCatchOp::create(cgf.
getBuilder(),
293 catchTokenTy, exnPtrTy, ehToken);
296 beginCatch.getCatchToken());
298 return beginCatch.getExnPtr();
304 mlir::Value ehToken,
const VarDecl &catchParam,
308 cir::InitCatchKind
kind;
313 kind = cir::InitCatchKind::Reference;
319 kind = !copyExpr ? cir::InitCatchKind::TrivialCopy
320 : cir::InitCatchKind::NonTrivialCopy;
323 if (catchType->hasPointerRepresentation()) {
327 kind = cir::InitCatchKind::Objc;
333 kind = cir::InitCatchKind::Pointer;
337 kind = cir::InitCatchKind::Scalar;
344 cir::InitCatchParamOp::create(builder, cgf.
getLoc(loc), exnPtr,
345 var.getAllocatedAddress().getPointer(),
kind);
352 mlir::Value ehToken) {
381 mlir::Location loc =
getLoc(
s.getSourceRange());
384 mlir::OpBuilder::InsertPoint scopeIP;
385 cir::ScopeOp::create(
387 [&](mlir::OpBuilder &
b, mlir::Location loc) {
388 scopeIP = builder.saveInsertionPoint();
392 auto funcOp = mlir::cast<cir::FuncOp>(
curFn);
393 if (!funcOp.getPersonality())
396 mlir::OpBuilder::InsertionGuard guard(builder);
397 builder.restoreInsertionPoint(scopeIP);
402 const bool isTargetDevice =
403 (
cgm.getLangOpts().OpenMPIsTargetDevice && (t.isNVPTX() || t.isAMDGCN()));
404 if (isTargetDevice) {
405 cgm.errorNYI(
"emitCXXTryStmt: OpenMP target region offloaded to GPU");
406 return mlir::success();
409 mlir::Location tryLoc =
getLoc(
s.getBeginLoc());
413 builder.getInsertionBlock()};
416 cgm.errorNYI(
"enterCXXTryStmt: EHAsynch");
417 return mlir::failure();
421 mlir::LogicalResult tryRes = mlir::success();
422 auto tryOp = cir::TryOp::create(
425 [&](mlir::OpBuilder &
b, mlir::Location loc) {
430 if (bodyCallback(*this).failed())
431 tryRes = mlir::failure();
433 cir::YieldOp::create(builder, loc);
436 [&](mlir::OpBuilder &
b, mlir::Location loc,
437 mlir::OperationState &result) {
438 mlir::OpBuilder::InsertionGuard guard(
b);
439 bool hasCatchAll =
false;
440 unsigned numHandlers =
s.getNumHandlers();
442 for (
unsigned i = 0; i != numHandlers; ++i) {
446 mlir::Region *region = result.addRegion();
447 builder.createBlock(region, {}, {ehTokenTy}, {loc});
452 mlir::Region *region = result.addRegion();
453 mlir::Block *unwindBlock =
454 builder.createBlock(region, {}, {ehTokenTy}, {loc});
455 cir::ResumeOp::create(builder, loc, unwindBlock->getArgument(0));
461 return mlir::failure();
464 tryOp.setHandlerTypesAttr(
470 unsigned numHandlers =
s.getNumHandlers();
471 for (
unsigned i = 0; i != numHandlers; ++i) {
473 mlir::Region *handler = &tryOp.getHandlerRegions()[i];
476 mlir::OpBuilder::InsertionGuard guard(builder);
477 builder.setInsertionPointToStart(&handler->front());
480 mlir::Value ehToken = handler->front().getArgument(0);
495 [[maybe_unused]] mlir::LogicalResult emitResult =
497 assert(emitResult.succeeded() &&
"failed to emit catch handler block");
509 mlir::Block *block = &handler->getBlocks().back();
510 if (block->empty() ||
511 !block->back().hasTrait<mlir::OpTrait::IsTerminator>()) {
512 mlir::OpBuilder::InsertionGuard guard(builder);
513 builder.setInsertionPointToEnd(block);
514 builder.createYield(handlerLoc);
518 return mlir::success();
522 if (
s.getTryBlock()->body_empty())
523 return mlir::LogicalResult::success();
530 return cgf.
emitStmt(
s.getTryBlock(),
true);
532 ~simpleTryBodyEmitter()
override =
default;
535 simpleTryBodyEmitter emitter{
s};
551 if (!lo.Exceptions || lo.IgnoreExceptions) {
552 if (!lo.Borland && !lo.MicrosoftExt)
554 cgm.errorNYI(
"isInvokeDest: no exceptions or ignore exception");
559 if (lo.CUDA && lo.CUDAIsDevice)
562 return ehStack.requiresCatchOrCleanup();
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
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 mlir::Value callBeginCatch(CIRGenFunction &cgf, mlir::Value ehToken, mlir::Type exnPtrTy)
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 void initCatchParam(CIRGenFunction &cgf, CIRGenBuilderTy &builder, mlir::Value ehToken, const VarDecl &catchParam, SourceLocation loc)
A "special initializer" callback for initializing a catch parameter during catch initialization.
static const EHPersonality & getSEHPersonalityMSVC(const llvm::Triple &triple)
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
__device__ __2f16 float __ockl_bool s
cir::PointerType getVoidPtrTy(clang::LangAS langAS=clang::LangAS::Default)
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
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.
static cir::TypeEvaluationKind getEvaluationKind(clang::QualType type)
Return the cir::TypeEvaluationKind of QualType type.
AutoVarEmission emitAutoVarAlloca(const clang::VarDecl &d, mlir::OpBuilder::InsertPoint ip={})
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)
void emitBeginCatch(const CXXCatchStmt *catchStmt, mlir::Value ehToken)
Begins a catch statement by initializing the catch variable and calling __cxa_begin_catch.
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.
CIRGenBuilderTy & getBuilder()
mlir::MLIRContext & getMLIRContext()
void emitCXXThrowExpr(const CXXThrowExpr *e)
bool isCatchOrCleanupRequired()
CIRGenFunction(CIRGenModule &cgm, CIRGenBuilderTy &builder, bool suppressNewContext=false)
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})
void emitAutoVarCleanups(const AutoVarEmission &emission)
This class organizes the cross-function state that is used while generating CIR code.
clang::ASTContext & getASTContext() const
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
Information for lazily generating a cleanup.
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.
Qualifiers getQualifiers() const
Retrieve all qualifiers.
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.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
ObjCLifetime getObjCLifetime() const
Encodes a location in the source.
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isObjCObjectPointerType() const
Represents a variable declaration or definition.
const Expr * getInit() const
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
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