================
@@ -374,6 +374,202 @@ mlir::Attribute buildRecord(ConstantEmitter &emitter, 
const APValue &val,
 }
 } // namespace ConstRecordBuilder
 
+//===----------------------------------------------------------------------===//
+//                         DesignatedInitUpdateExpr
+//===----------------------------------------------------------------------===//
+
+// Forward declaration.
+static bool emitDesignatedInitUpdater(ConstantEmitter &emitter,
+                                      CIRGenModule &cgm, QualType type,
+                                      mlir::Attribute &base,
+                                      const InitListExpr *updater);
+
+/// Apply a DesignatedInitUpdateExpr's updater InitListExpr to an existing
+/// record constant. The record's fields are decomposed, modified according to
+/// the updater, and reassembled.
+static bool updateRecord(ConstantEmitter &emitter, CIRGenModule &cgm,
+                         const RecordDecl *rd, mlir::Attribute &base,
+                         const InitListExpr *updater) {
+  CIRGenBuilderTy &builder = cgm.getBuilder();
+  const CIRGenRecordLayout &cirLayout =
+      cgm.getTypes().getCIRGenRecordLayout(rd);
+  cir::RecordType recordTy = cirLayout.getCIRType();
+
+  // Decompose the base record into mutable elements.
+  llvm::SmallVector<mlir::Attribute> elements;
+  if (auto recAttr = mlir::dyn_cast<cir::ConstRecordAttr>(base)) {
+    for (mlir::Attribute m : recAttr.getMembers())
+      elements.push_back(m);
+  } else if (mlir::isa<cir::ZeroAttr>(base)) {
+    // Zero-initialized base: fill with per-field zero attrs.
+    elements.resize(recordTy.getNumElements());
+    for (unsigned i = 0; i < recordTy.getNumElements(); ++i)
+      elements[i] = builder.getZeroInitAttr(recordTy.getElementType(i));
+  } else if (mlir::isa<cir::ConstVectorAttr>(base) ||
+             mlir::isa<cir::PoisonAttr>(base)) {
+    cgm.errorNYI("updateRecord: ConstVectorAttr or PoisonAttr base");
+    return false;
+  } else {
+    cgm.errorNYI("updateRecord: unsupported base attribute kind");
+    return false;
+  }
+
+  unsigned fieldNo = 0;
+  for (const FieldDecl *field : rd->fields()) {
+    if (field->isUnnamedBitField()) {
+      ++fieldNo;
----------------
andykaylor wrote:

This looks wrong. Classic codegen has separate variables for ElementNo, which 
is used only to get the init value from the updater, and FieldNo, which is used 
for everything else. It doesn't increment ElementNo in the case of unnamed 
bitfields, but otherwise they are in step.

I think your handling will be off when an unnamed bitfield is present. Can you 
add a test for that?

https://github.com/llvm/llvm-project/pull/194238
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to