Skip to content

Commit 1029b19

Browse files
authored
[CIR][CIRGen] virtual table pointer initialization without ctor (#1283)
Corresponding [OG code](https://github.com/llvm/clangir/blob/ef20d053b3d78c9d4c135e2811b303b7e5016d30/clang/lib/CodeGen/CGExprConstant.cpp#L846). [OG generated code here](https://godbolt.org/z/x6q333dMn), one notable diff is we're missing `inrange` which is reported in [issue 886 ](#886). For now, I'm still using GlobalViewAttr to implement it so we can move things fast. But it might be worth considering approach [Comments in issue 258](#258), especially we could incoporate [inrange info](#886) to the attribute suggested there.
1 parent 3891619 commit 1029b19

File tree

2 files changed

+34
-5
lines changed

2 files changed

+34
-5
lines changed

clang/lib/CIR/CodeGen/CIRGenExprConst.cpp

+19-4
Original file line numberDiff line numberDiff line change
@@ -736,12 +736,27 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
736736
const CXXRecordDecl *VTableClass,
737737
CharUnits Offset) {
738738
const ASTRecordLayout &Layout = CGM.getASTContext().getASTRecordLayout(RD);
739-
740739
if (const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
741740
// Add a vtable pointer, if we need one and it hasn't already been added.
742-
if (Layout.hasOwnVFPtr())
743-
llvm_unreachable("NYI");
744-
741+
if (Layout.hasOwnVFPtr()) {
742+
CIRGenBuilderTy &builder = CGM.getBuilder();
743+
cir::GlobalOp vtable =
744+
CGM.getCXXABI().getAddrOfVTable(VTableClass, CharUnits());
745+
clang::VTableLayout::AddressPointLocation addressPoint =
746+
CGM.getItaniumVTableContext()
747+
.getVTableLayout(VTableClass)
748+
.getAddressPoint(BaseSubobject(CD, Offset));
749+
assert(!cir::MissingFeatures::ptrAuth());
750+
mlir::ArrayAttr indices = builder.getArrayAttr({
751+
builder.getI32IntegerAttr(0),
752+
builder.getI32IntegerAttr(addressPoint.VTableIndex),
753+
builder.getI32IntegerAttr(addressPoint.AddressPointIndex),
754+
});
755+
cir::GlobalViewAttr vtableInit =
756+
CGM.getBuilder().getGlobalViewAttr(vtable, indices);
757+
if (!AppendBytes(Offset, vtableInit))
758+
return false;
759+
}
745760
// Accumulate and sort bases, in order to visit them in address order, which
746761
// may not be the same as declaration order.
747762
SmallVector<BaseInfo, 8> Bases;
+15-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
11
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
22
// RUN: FileCheck --input-file=%t.cir %s
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm -o - %s \
4+
// RUN: | opt -S -passes=instcombine,mem2reg,simplifycfg -o %t.ll
5+
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
36

47
struct S {
58
virtual void key();
69
virtual void nonKey() {}
7-
};
10+
} sobj;
811

912
void S::key() {}
1013

14+
// CHECK-DAG: !ty_anon_struct1 = !cir.struct<struct {!cir.array<!cir.ptr<!u8i> x 4>}>
15+
// CHECK-DAG: !ty_anon_struct2 = !cir.struct<struct {!cir.ptr<!ty_anon_struct1>}>
16+
1117
// The definition of the key function should result in the vtable being emitted.
1218
// CHECK: cir.global external @_ZTV1S = #cir.vtable
19+
// LLVM: @_ZTV1S = global { [4 x ptr] } { [4 x ptr]
20+
// LLVM-SAME: [ptr null, ptr @_ZTI1S, ptr @_ZN1S3keyEv, ptr @_ZN1S6nonKeyEv] }, align 8
21+
22+
// CHECK: cir.global external @sobj = #cir.const_struct
23+
// CHECK-SAME: <{#cir.global_view<@_ZTV1S, [0 : i32, 0 : i32, 2 : i32]> :
24+
// CHECK-SAME: !cir.ptr<!ty_anon_struct1>}> : !ty_anon_struct2 {alignment = 8 : i64}
25+
// LLVM: @sobj = global { ptr } { ptr getelementptr inbounds
26+
// LLVM-SAME: ({ [4 x ptr] }, ptr @_ZTV1S, i32 0, i32 0, i32 2) }, align 8
1327

1428
// The reference from the vtable should result in nonKey being emitted.
1529
// CHECK: cir.func linkonce_odr @_ZN1S6nonKeyEv({{.*}} {

0 commit comments

Comments
 (0)