Author: Andy Kaylor Date: 2025-05-30T16:01:12-07:00 New Revision: 94dfe875b01655cf2f1777973906da6ae0d96e7a
URL: https://github.com/llvm/llvm-project/commit/94dfe875b01655cf2f1777973906da6ae0d96e7a DIFF: https://github.com/llvm/llvm-project/commit/94dfe875b01655cf2f1777973906da6ae0d96e7a.diff LOG: [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. Added: Modified: clang/lib/CIR/CodeGen/CIRGenTypes.cpp clang/test/CIR/CodeGen/struct.cpp Removed: ################################################################################ diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index 0665ea0506875..d962372a4bcc0 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -152,11 +152,13 @@ isSafeToConvert(const RecordDecl *rd, CIRGenTypes &cgt, // out, don't do it. This includes virtual base classes which get laid out // when a class is translated, even though they aren't embedded by-value into // the class. - if (isa<CXXRecordDecl>(rd)) { - assert(!cir::MissingFeatures::cxxSupport()); - cgt.getCGModule().errorNYI(rd->getSourceRange(), - "isSafeToConvert: CXXRecordDecl"); - return false; + if (auto *crd = dyn_cast<CXXRecordDecl>(rd)) { + if (crd->getNumBases() > 0) { + assert(!cir::MissingFeatures::cxxSupport()); + cgt.getCGModule().errorNYI(rd->getSourceRange(), + "isSafeToConvert: CXXRecordDecl with bases"); + return false; + } } // If this type would require laying out members that are currently being laid diff --git a/clang/test/CIR/CodeGen/struct.cpp b/clang/test/CIR/CodeGen/struct.cpp index 8b9c51bebf97f..c8406f811a462 100644 --- a/clang/test/CIR/CodeGen/struct.cpp +++ b/clang/test/CIR/CodeGen/struct.cpp @@ -65,3 +65,31 @@ char f2(CompleteS &s) { // OGCG: %[[S_REF:.*]] = load ptr, ptr %[[S_ADDR]] // OGCG: %[[S_ADDR2:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[S_REF]], i32 0, i32 1 // OGCG: %[[S_B:.*]] = load i8, ptr %[[S_ADDR2]] + +struct Inner { + int n; +}; + +struct Outer { + Inner i; +}; + +void f3() { + Outer o; + o.i.n; +} + +// CIR: cir.func @_Z2f3v() +// CIR: %[[O:.*]] = cir.alloca !rec_Outer, !cir.ptr<!rec_Outer>, ["o"] +// CIR: %[[O_I:.*]] = cir.get_member %[[O]][0] {name = "i"} +// CIR: %[[O_I_N:.*]] = cir.get_member %[[O_I]][0] {name = "n"} + +// LLVM: define{{.*}} void @_Z2f3v() +// LLVM: %[[O:.*]] = alloca %struct.Outer, i64 1, align 4 +// LLVM: %[[O_I:.*]] = getelementptr %struct.Outer, ptr %[[O]], i32 0, i32 0 +// LLVM: %[[O_I_N:.*]] = getelementptr %struct.Inner, ptr %[[O_I]], i32 0, i32 0 + +// OGCG: define{{.*}} void @_Z2f3v() +// OGCG: %[[O:.*]] = alloca %struct.Outer, align 4 +// OGCG: %[[O_I:.*]] = getelementptr inbounds nuw %struct.Outer, ptr %[[O]], i32 0, i32 0 +// OGCG: %[[O_I_N:.*]] = getelementptr inbounds nuw %struct.Inner, ptr %[[O_I]], i32 0, i32 0 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits