================
@@ -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;
+ continue;
+ }
+ if (fieldNo >= updater->getNumInits())
+ break;
+
+ const Expr *init = updater->getInit(fieldNo);
+ ++fieldNo;
+
+ if (isa<NoInitExpr>(init))
+ continue;
+
+ if (!cirLayout.hasCIRField(field))
+ continue;
+
+ unsigned fieldIdx = cirLayout.getCIRFieldNo(field);
+
+ // When the updater contains a nested InitListExpr for a sub-aggregate,
+ // it represents additional overwriting of the current value (not a new
+ // independent constant).
+ if ((field->getType()->isArrayType() || field->getType()->isRecordType()))
{
+ if (auto *subILE = dyn_cast<InitListExpr>(init)) {
+ if (!emitDesignatedInitUpdater(emitter, cgm, field->getType(),
+ elements[fieldIdx], subILE))
+ return false;
+ continue;
+ }
+ // For non-InitListExpr aggregate inits (e.g. compound literals),
+ // fall through to the regular emission below.
+ }
+
+ mlir::Attribute eltAttr =
+ emitter.tryEmitPrivateForMemory(init, field->getType());
+ if (!eltAttr)
+ return false;
+
+ if (field->isBitField()) {
+ elements[fieldIdx] = ConstRecordBuilder::setBitfieldInit(
+ cgm, cirLayout, builder, field, elements[fieldIdx], eltAttr);
+ } else {
+ elements[fieldIdx] = eltAttr;
+ }
+ }
+
+ base = builder.getConstRecordOrZeroAttr(builder.getArrayAttr(elements),
+ recordTy.getPacked(),
+ recordTy.getPadded(), recordTy);
+ return true;
+}
+
+/// Apply a DesignatedInitUpdateExpr's updater InitListExpr to an existing
+/// array constant. Individual array elements are modified according to
+/// the updater.
+static bool updateArray(ConstantEmitter &emitter, CIRGenModule &cgm,
+ QualType type, mlir::Attribute &base,
+ const InitListExpr *updater) {
+ CIRGenBuilderTy &builder = cgm.getBuilder();
+ auto cat = cgm.getASTContext().getAsConstantArrayType(type);
+ if (!cat)
+ return false;
+
+ QualType elemType = cat->getElementType();
+ uint64_t numElements = cat->getZExtSize();
+
+ // Decompose the base array into mutable elements.
+ llvm::SmallVector<mlir::Attribute> elements;
+ elements.resize(numElements);
+
+ if (auto arrAttr = mlir::dyn_cast<cir::ConstArrayAttr>(base)) {
+ auto eltsAttr = mlir::dyn_cast<mlir::ArrayAttr>(arrAttr.getElts());
+ if (!eltsAttr) {
+ cgm.errorNYI("updateArray: string literal array base");
+ return false;
+ }
+ for (unsigned i = 0; i < eltsAttr.size(); ++i)
+ elements[i] = eltsAttr[i];
----------------
erichkeane wrote:
if you take my above, we can just do:
```
elements.insert(elements.begin(), eltsAttr.begin(), eltsAttr.end());
```
https://github.com/llvm/llvm-project/pull/194238
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits