Skip to content

Commit 94dfe87

Browse files
authored
[CIR] Enable support for nested struct members in C++ (#142205)
This enables us to compile C++ code with nested structures. The necessary support for this was already in place, but we were hitting an NYI error in a place where the implementation only needed to check for base classes. Base classes really aren't implemented yet, so the error is left in place but it is now behind a check for a non-zero number of bases so that the simple case is unblocked.
1 parent b4b3be7 commit 94dfe87

File tree

2 files changed

+35
-5
lines changed

2 files changed

+35
-5
lines changed

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,13 @@ isSafeToConvert(const RecordDecl *rd, CIRGenTypes &cgt,
152152
// out, don't do it. This includes virtual base classes which get laid out
153153
// when a class is translated, even though they aren't embedded by-value into
154154
// the class.
155-
if (isa<CXXRecordDecl>(rd)) {
156-
assert(!cir::MissingFeatures::cxxSupport());
157-
cgt.getCGModule().errorNYI(rd->getSourceRange(),
158-
"isSafeToConvert: CXXRecordDecl");
159-
return false;
155+
if (auto *crd = dyn_cast<CXXRecordDecl>(rd)) {
156+
if (crd->getNumBases() > 0) {
157+
assert(!cir::MissingFeatures::cxxSupport());
158+
cgt.getCGModule().errorNYI(rd->getSourceRange(),
159+
"isSafeToConvert: CXXRecordDecl with bases");
160+
return false;
161+
}
160162
}
161163

162164
// If this type would require laying out members that are currently being laid

clang/test/CIR/CodeGen/struct.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,31 @@ char f2(CompleteS &s) {
6565
// OGCG: %[[S_REF:.*]] = load ptr, ptr %[[S_ADDR]]
6666
// OGCG: %[[S_ADDR2:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[S_REF]], i32 0, i32 1
6767
// OGCG: %[[S_B:.*]] = load i8, ptr %[[S_ADDR2]]
68+
69+
struct Inner {
70+
int n;
71+
};
72+
73+
struct Outer {
74+
Inner i;
75+
};
76+
77+
void f3() {
78+
Outer o;
79+
o.i.n;
80+
}
81+
82+
// CIR: cir.func @_Z2f3v()
83+
// CIR: %[[O:.*]] = cir.alloca !rec_Outer, !cir.ptr<!rec_Outer>, ["o"]
84+
// CIR: %[[O_I:.*]] = cir.get_member %[[O]][0] {name = "i"}
85+
// CIR: %[[O_I_N:.*]] = cir.get_member %[[O_I]][0] {name = "n"}
86+
87+
// LLVM: define{{.*}} void @_Z2f3v()
88+
// LLVM: %[[O:.*]] = alloca %struct.Outer, i64 1, align 4
89+
// LLVM: %[[O_I:.*]] = getelementptr %struct.Outer, ptr %[[O]], i32 0, i32 0
90+
// LLVM: %[[O_I_N:.*]] = getelementptr %struct.Inner, ptr %[[O_I]], i32 0, i32 0
91+
92+
// OGCG: define{{.*}} void @_Z2f3v()
93+
// OGCG: %[[O:.*]] = alloca %struct.Outer, align 4
94+
// OGCG: %[[O_I:.*]] = getelementptr inbounds nuw %struct.Outer, ptr %[[O]], i32 0, i32 0
95+
// OGCG: %[[O_I_N:.*]] = getelementptr inbounds nuw %struct.Inner, ptr %[[O_I]], i32 0, i32 0

0 commit comments

Comments
 (0)