================
@@ -306,3 +320,71 @@ CIRGenTypes::computeRecordLayout(const RecordDecl *rd, 
cir::RecordType *ty) {
   // TODO: implement verification
   return rl;
 }
+
+void CIRRecordLowering::lowerUnion() {
+  CharUnits layoutSize = astRecordLayout.getSize();
+  mlir::Type storageType = nullptr;
+  bool seenNamedMember = false;
+
+  // Iterate through the fields setting bitFieldInfo and the Fields array. Also
+  // locate the "most appropriate" storage type.  The heuristic for finding the
+  // storage type isn't necessary, the first (non-0-length-bitfield) field's
+  // type would work fine and be simpler but would be different than what we've
+  // been doing and cause lit tests to change.
+  for (const FieldDecl *field : recordDecl->fields()) {
+    mlir::Type fieldType;
+    if (field->isBitField())
+      cirGenTypes.getCGModule().errorNYI(recordDecl->getSourceRange(),
+                                         "bitfields in lowerUnion");
+    else
+      fieldType = getStorageType(field);
+
+    fields[field->getCanonicalDecl()] = 0;
+
+    // Compute zero-initializable status.
+    // This union might not be zero initialized: it may contain a pointer to
+    // data member which might have some exotic initialization sequence.
+    // If this is the case, then we aught not to try and come up with a 
"better"
+    // type, it might not be very easy to come up with a Constant which
+    // correctly initializes it.
+    if (!seenNamedMember) {
+      seenNamedMember = field->getIdentifier();
+      if (!seenNamedMember)
+        if (const RecordDecl *fieldRD = field->getType()->getAsRecordDecl())
+          seenNamedMember = fieldRD->findFirstNamedDataMember();
+      if (seenNamedMember && !isZeroInitializable(field)) {
+        zeroInitializable = zeroInitializableAsBase = false;
+        storageType = fieldType;
+      }
+    }
+
+    // Because our union isn't zero initializable, we won't be getting a better
+    // storage type.
+    if (!zeroInitializable)
+      continue;
+
+    // Conditionally update our storage type if we've got a new "better" one.
+    if (!storageType || getAlignment(fieldType) > getAlignment(storageType) ||
+        (getAlignment(fieldType) == getAlignment(storageType) &&
+         getSize(fieldType) > getSize(storageType)))
+      storageType = fieldType;
+
+    // NOTE(cir): Track all union member's types, not just the largest one. It
+    // allows for proper type-checking and retain more info for analisys.
+    fieldTypes.push_back(fieldType);
+  }
+
+  if (!storageType)
+    cirGenTypes.getCGModule().errorNYI(recordDecl->getSourceRange(),
+                                       "No-storage Union NYI");
+
+  if (layoutSize < getSize(storageType))
+    storageType = getByteArrayType(layoutSize);
+
+  // NOTE(cir): Defer padding calculations to the lowering process.
----------------
andykaylor wrote:

I don't understand this comment. Isn't calculating padding exactly what we just 
did?

https://github.com/llvm/llvm-project/pull/137501
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to