https://github.com/andykaylor created 
https://github.com/llvm/llvm-project/pull/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.

>From e58c99e70d219bed86055fc509a6de526292d56c Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akay...@nvidia.com>
Date: Fri, 30 May 2025 12:38:25 -0700
Subject: [PATCH] [CIR] Enable support for nested struct members in C++

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.
---
 clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 12 +++++++-----
 clang/test/CIR/CodeGen/struct.cpp     | 28 +++++++++++++++++++++++++++
 2 files changed, 35 insertions(+), 5 deletions(-)

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 5948d1423d448..1c0c311a2f1b6 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

Reply via email to