llvm-project/clang/lib/CIR/CodeGen/CIRGenException.cpp
Amr Hesham c25a2c7284
[CIR] Upstream Exception with empty try block (#162737)
Upstream, the basic support for the C++ try catch statement with an
empty try block

Issue https://github.com/llvm/llvm-project/issues/154992
2025-10-10 17:57:47 +02:00

75 lines
2.6 KiB
C++

//===--- CIRGenException.cpp - Emit CIR Code for C++ exceptions -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This contains code dealing with C++ exception related code generation.
//
//===----------------------------------------------------------------------===//
#include "CIRGenCXXABI.h"
#include "CIRGenFunction.h"
#include "clang/AST/StmtVisitor.h"
using namespace clang;
using namespace clang::CIRGen;
void CIRGenFunction::emitCXXThrowExpr(const CXXThrowExpr *e) {
const llvm::Triple &triple = getTarget().getTriple();
if (cgm.getLangOpts().OpenMPIsTargetDevice &&
(triple.isNVPTX() || triple.isAMDGCN())) {
cgm.errorNYI("emitCXXThrowExpr OpenMP with NVPTX or AMDGCN Triples");
return;
}
if (const Expr *subExpr = e->getSubExpr()) {
QualType throwType = subExpr->getType();
if (throwType->isObjCObjectPointerType()) {
cgm.errorNYI("emitCXXThrowExpr ObjCObjectPointerType");
return;
}
cgm.getCXXABI().emitThrow(*this, e);
return;
}
cgm.getCXXABI().emitRethrow(*this, /*isNoReturn=*/true);
}
void CIRGenFunction::emitAnyExprToExn(const Expr *e, Address addr) {
// Make sure the exception object is cleaned up if there's an
// exception during initialization.
assert(!cir::MissingFeatures::ehCleanupScope());
// __cxa_allocate_exception returns a void*; we need to cast this
// to the appropriate type for the object.
mlir::Type ty = convertTypeForMem(e->getType());
Address typedAddr = addr.withElementType(builder, ty);
// From LLVM's codegen:
// FIXME: this isn't quite right! If there's a final unelided call
// to a copy constructor, then according to [except.terminate]p1 we
// must call std::terminate() if that constructor throws, because
// technically that copy occurs after the exception expression is
// evaluated but before the exception is caught. But the best way
// to handle that is to teach EmitAggExpr to do the final copy
// differently if it can't be elided.
emitAnyExprToMem(e, typedAddr, e->getType().getQualifiers(),
/*isInitializer=*/true);
// Deactivate the cleanup block.
assert(!cir::MissingFeatures::ehCleanupScope());
}
mlir::LogicalResult CIRGenFunction::emitCXXTryStmt(const CXXTryStmt &s) {
if (s.getTryBlock()->body_empty())
return mlir::LogicalResult::success();
cgm.errorNYI("exitCXXTryStmt: CXXTryStmt with non-empty body");
return mlir::LogicalResult::success();
}