Skip to content

Commit 32e3971

Browse files
authored
[CIR] Support inheritance in InitListExpr (#1684)
convert from codegen ```c++ assert(!Base.isVirtual() && "should not see vbases here"); auto *BaseRD = Base.getType()->getAsCXXRecordDecl(); Address V = CGF.GetAddressOfDirectBaseInCompleteClass( Dest.getAddress(), CXXRD, BaseRD, /*isBaseVirtual*/ false); AggValueSlot AggSlot = AggValueSlot::forAddr( V, Qualifiers(), AggValueSlot::IsDestructed, AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased, CGF.getOverlapForBaseInit(CXXRD, BaseRD, Base.isVirtual())); CGF.EmitAggExpr(InitExprs[curInitIndex++], AggSlot); if (QualType::DestructionKind dtorKind = Base.getType().isDestructedType()) CGF.pushDestroyAndDeferDeactivation(dtorKind, V, Base.getType()); ```
1 parent daaf817 commit 32e3971

File tree

2 files changed

+85
-7
lines changed

2 files changed

+85
-7
lines changed

clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,9 +1252,8 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
12521252
return;
12531253
}
12541254
#endif
1255-
1256-
AggValueSlot Dest = EnsureSlot(CGF.getLoc(ExprToVisit->getSourceRange()),
1257-
ExprToVisit->getType());
1255+
const mlir::Location loc = CGF.getLoc(ExprToVisit->getSourceRange());
1256+
AggValueSlot Dest = EnsureSlot(loc, ExprToVisit->getType());
12581257

12591258
LValue DestLV = CGF.makeAddrLValue(Dest.getAddress(), ExprToVisit->getType());
12601259

@@ -1294,8 +1293,20 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
12941293
if (auto *CXXRD = dyn_cast<CXXRecordDecl>(record)) {
12951294
assert(NumInitElements >= CXXRD->getNumBases() &&
12961295
"missing initializer for base class");
1297-
for ([[maybe_unused]] auto &Base : CXXRD->bases()) {
1298-
llvm_unreachable("NYI");
1296+
for (auto &Base : CXXRD->bases()) {
1297+
assert(!Base.isVirtual() && "should not see vbases here");
1298+
auto *BaseRD = Base.getType()->getAsCXXRecordDecl();
1299+
Address address = CGF.getAddressOfDirectBaseInCompleteClass(
1300+
loc, Dest.getAddress(), CXXRD, BaseRD,
1301+
/*isBaseVirtual*/ false);
1302+
AggValueSlot aggSlot = AggValueSlot::forAddr(
1303+
address, Qualifiers(), AggValueSlot::IsDestructed,
1304+
AggValueSlot::DoesNotNeedGCBarriers, AggValueSlot::IsNotAliased,
1305+
CGF.getOverlapForBaseInit(CXXRD, BaseRD, false));
1306+
CGF.emitAggExpr(InitExprs[curInitIndex++], aggSlot);
1307+
if (QualType::DestructionKind dtorKind =
1308+
Base.getType().isDestructedType())
1309+
CGF.pushDestroyAndDeferDeactivation(dtorKind, address, Base.getType());
12991310
}
13001311
}
13011312

@@ -1329,8 +1340,7 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
13291340
emitInitializationToLValue(InitExprs[0], FieldLoc);
13301341
} else {
13311342
// Default-initialize to null.
1332-
emitNullInitializationToLValue(CGF.getLoc(ExprToVisit->getSourceRange()),
1333-
FieldLoc);
1343+
emitNullInitializationToLValue(loc, FieldLoc);
13341344
}
13351345

13361346
return;
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
4+
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
5+
6+
struct A1 {
7+
A1();
8+
};
9+
10+
class B : public A1 {};
11+
12+
void f1() {
13+
B v{};
14+
}
15+
16+
// CIR: cir.func dso_local @_Z2f1v()
17+
// CIR: %0 = cir.alloca !rec_B, !cir.ptr<!rec_B>, ["v", init]
18+
// CIR: %1 = cir.base_class_addr %0 : !cir.ptr<!rec_B> nonnull [0] -> !cir.ptr<!rec_A1>
19+
// CIR: cir.call @_ZN2A1C2Ev(%1) : (!cir.ptr<!rec_A1>) -> ()
20+
// CIR: cir.return
21+
// LLVM: define dso_local void @_Z2f1v()
22+
// LLVM: %1 = alloca %class.B, i64 1, align 1
23+
// LLVM: call void @_ZN2A1C2Ev(ptr %1)
24+
// LLVM: ret void
25+
26+
struct A2 {
27+
A2();
28+
};
29+
class C : public A1, public A2 {};
30+
31+
void f2() {
32+
C v{};
33+
}
34+
35+
// CIR: cir.func dso_local @_Z2f2v()
36+
// CIR: %0 = cir.alloca !rec_C, !cir.ptr<!rec_C>, ["v", init]
37+
// CIR: %1 = cir.base_class_addr %0 : !cir.ptr<!rec_C> nonnull [0] -> !cir.ptr<!rec_A1>
38+
// CIR: cir.call @_ZN2A1C2Ev(%1) : (!cir.ptr<!rec_A1>) -> ()
39+
// CIR: %2 = cir.base_class_addr %0 : !cir.ptr<!rec_C> nonnull [0] -> !cir.ptr<!rec_A2>
40+
// CIR: cir.call @_ZN2A2C2Ev(%2) : (!cir.ptr<!rec_A2>) -> ()
41+
// CIR: cir.return
42+
// LLVM: define dso_local void @_Z2f2v()
43+
// LLVM: %1 = alloca %class.C, i64 1, align 1
44+
// LLVM: call void @_ZN2A1C2Ev(ptr %1)
45+
// LLVM: call void @_ZN2A2C2Ev(ptr %1)
46+
// LLVM: ret void
47+
48+
struct A3 {
49+
A3();
50+
~A3();
51+
};
52+
class D : public A3 {};
53+
54+
void f3() {
55+
D v{};
56+
}
57+
58+
// CIR: cir.func dso_local @_Z2f3v()
59+
// CIR: %0 = cir.alloca !rec_D, !cir.ptr<!rec_D>, ["v", init]
60+
// CIR: %1 = cir.base_class_addr %0 : !cir.ptr<!rec_D> nonnull [0] -> !cir.ptr<!rec_A3>
61+
// CIR: cir.call @_ZN2A3C2Ev(%1) : (!cir.ptr<!rec_A3>) -> ()
62+
// CIR: cir.call @_ZN1DD1Ev(%0) : (!cir.ptr<!rec_D>) -> ()
63+
// CIR: cir.return
64+
// LLVM: define dso_local void @_Z2f3v()
65+
// LLVM: %1 = alloca %class.D, i64 1, align 1
66+
// LLVM: call void @_ZN2A3C2Ev(ptr %1)
67+
// LLVM: call void @_ZN1DD1Ev(ptr %1)
68+
// LLVM: ret void

0 commit comments

Comments
 (0)