Skip to content

Commit e91de85

Browse files
committed
[CIR][CIRGen] Support pure and deleted virtual functions (llvm#823)
This is a straightforward adaption of existing CodeGen logic. While I'm here, move block comments inside their blocks, so that they look nicer.
1 parent 26584c5 commit e91de85

File tree

5 files changed

+51
-28
lines changed

5 files changed

+51
-28
lines changed

clang/lib/CIR/CodeGen/CIRGenCXXABI.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,12 @@ class CIRGenCXXABI {
235235
BaseSubobject Base,
236236
const CXXRecordDecl *NearestVBase) = 0;
237237

238+
/// Gets the pure virtual member call function.
239+
virtual StringRef getPureVirtualCallName() = 0;
240+
241+
/// Gets the deleted virtual member call name.
242+
virtual StringRef getDeletedVirtualCallName() = 0;
243+
238244
/// Specify how one should pass an argument of a record type.
239245
enum class RecordArgABI {
240246
/// Pass it using the normal C aggregate rules for the ABI, potentially

clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ class CIRGenItaniumCXXABI : public cir::CIRGenCXXABI {
215215
return false;
216216
}
217217

218+
StringRef getPureVirtualCallName() override { return "__cxa_pure_virtual"; }
219+
StringRef getDeletedVirtualCallName() override {
220+
return "__cxa_deleted_virtual";
221+
}
222+
218223
/// TODO(cir): seems like could be shared between LLVM IR and CIR codegen.
219224
bool mayNeedDestruction(const VarDecl *VD) const {
220225
if (VD->needsDestruction(getContext()))

clang/lib/CIR/CodeGen/CIRGenVTables.cpp

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,7 @@ void CIRGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
217217
llvm_unreachable("NYI");
218218
}
219219

220-
[[maybe_unused]] auto getSpecialVirtualFn =
221-
[&](StringRef name) -> mlir::Attribute {
220+
auto getSpecialVirtualFn = [&](StringRef name) -> mlir::cir::FuncOp {
222221
// FIXME(PR43094): When merging comdat groups, lld can select a local
223222
// symbol as the signature symbol even though it cannot be accessed
224223
// outside that symbol's TU. The relative vtables ABI would make
@@ -235,45 +234,41 @@ void CIRGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
235234
CGM.getTriple().isNVPTX())
236235
llvm_unreachable("NYI");
237236

238-
llvm_unreachable("NYI");
239-
// llvm::FunctionType *fnTy =
240-
// llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
241-
// llvm::Constant *fn = cast<llvm::Constant>(
242-
// CGM.CreateRuntimeFunction(fnTy, name).getCallee());
243-
// if (auto f = dyn_cast<llvm::Function>(fn))
244-
// f->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
245-
// return llvm::ConstantExpr::getBitCast(fn, CGM.Int8PtrTy);
237+
mlir::cir::FuncType fnTy =
238+
CGM.getBuilder().getFuncType({}, CGM.getBuilder().getVoidTy());
239+
mlir::cir::FuncOp fnPtr = CGM.createRuntimeFunction(fnTy, name);
240+
// LLVM codegen handles unnamedAddr
241+
assert(!MissingFeatures::unnamedAddr());
242+
return fnPtr;
246243
};
247244

248245
mlir::cir::FuncOp fnPtr;
249-
// Pure virtual member functions.
250246
if (cast<CXXMethodDecl>(GD.getDecl())->isPureVirtual()) {
251-
llvm_unreachable("NYI");
252-
// if (!PureVirtualFn)
253-
// PureVirtualFn =
254-
// getSpecialVirtualFn(CGM.getCXXABI().GetPureVirtualCallName());
255-
// fnPtr = PureVirtualFn;
247+
// Pure virtual member functions.
248+
if (!PureVirtualFn)
249+
PureVirtualFn =
250+
getSpecialVirtualFn(CGM.getCXXABI().getPureVirtualCallName());
251+
fnPtr = PureVirtualFn;
256252

257-
// Deleted virtual member functions.
258253
} else if (cast<CXXMethodDecl>(GD.getDecl())->isDeleted()) {
259-
llvm_unreachable("NYI");
260-
// if (!DeletedVirtualFn)
261-
// DeletedVirtualFn =
262-
// getSpecialVirtualFn(CGM.getCXXABI().GetDeletedVirtualCallName());
263-
// fnPtr = DeletedVirtualFn;
254+
// Deleted virtual member functions.
255+
if (!DeletedVirtualFn)
256+
DeletedVirtualFn =
257+
getSpecialVirtualFn(CGM.getCXXABI().getDeletedVirtualCallName());
258+
fnPtr = DeletedVirtualFn;
264259

265-
// Thunks.
266260
} else if (nextVTableThunkIndex < layout.vtable_thunks().size() &&
267261
layout.vtable_thunks()[nextVTableThunkIndex].first ==
268262
componentIndex) {
263+
// Thunks.
269264
llvm_unreachable("NYI");
270265
// auto &thunkInfo = layout.vtable_thunks()[nextVTableThunkIndex].second;
271266

272267
// nextVTableThunkIndex++;
273268
// fnPtr = maybeEmitThunk(GD, thunkInfo, /*ForVTable=*/true);
274269

275-
// Otherwise we can use the method definition directly.
276270
} else {
271+
// Otherwise we can use the method definition directly.
277272
auto fnTy = CGM.getTypes().GetFunctionTypeForVTable(GD);
278273
fnPtr = CGM.GetAddrOfFunction(GD, fnTy, /*ForVTable=*/true);
279274
}

clang/lib/CIR/CodeGen/CIRGenVTables.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "clang/AST/GlobalDecl.h"
2020
#include "clang/AST/VTableBuilder.h"
2121
#include "clang/Basic/ABI.h"
22+
#include "clang/CIR/Dialect/IR/CIRDialect.h"
2223
#include "llvm/ADT/DenseMap.h"
2324

2425
namespace clang {
@@ -52,11 +53,11 @@ class CIRGenVTables {
5253
/// indices.
5354
SecondaryVirtualPointerIndicesMapTy SecondaryVirtualPointerIndices;
5455

55-
// /// Cache for the pure virtual member call function.
56-
// llvm::Constant *PureVirtualFn = nullptr;
56+
/// Cache for the pure virtual member call function.
57+
mlir::cir::FuncOp PureVirtualFn = nullptr;
5758

58-
// /// Cache for the deleted virtual member call function.
59-
// llvm::Constant *DeletedVirtualFn = nullptr;
59+
/// Cache for the deleted virtual member call function.
60+
mlir::cir::FuncOp DeletedVirtualFn = nullptr;
6061

6162
// /// Get the address of a thunk and emit it if necessary.
6263
// llvm::Constant *maybeEmitThunk(GlobalDecl GD,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s
3+
4+
// Check that pure and deleted virtual functions are correctly emitted in the
5+
// vtable.
6+
class A {
7+
A();
8+
virtual void pure() = 0;
9+
virtual void deleted() = delete;
10+
};
11+
12+
A::A() = default;
13+
14+
// CHECK: @_ZTV1A = #cir.vtable<{#cir.const_array<[#cir.ptr<null> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI1A> : !cir.ptr<!u8i>, #cir.global_view<@__cxa_pure_virtual> : !cir.ptr<!u8i>, #cir.global_view<@__cxa_deleted_virtual> : !cir.ptr<!u8i>]>
15+
// CHECK: cir.func private @__cxa_pure_virtual()
16+
// CHECK: cir.func private @__cxa_deleted_virtual()

0 commit comments

Comments
 (0)