Upstream, the basic support for the C++ try catch statement with an empty try block Issue https://github.com/llvm/llvm-project/issues/154992
75 lines
2.6 KiB
C++
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();
|
|
}
|