-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[CIR] Enable support for nested struct members in C++ #142205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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.
@llvm/pr-subscribers-clangir Author: Andy Kaylor (andykaylor) ChangesThis 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. Full diff: https://github.com/llvm/llvm-project/pull/142205.diff 2 Files Affected:
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
|
@llvm/pr-subscribers-clang Author: Andy Kaylor (andykaylor) ChangesThis 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. Full diff: https://github.com/llvm/llvm-project/pull/142205.diff 2 Files Affected:
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
|
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.