================
@@ -851,72 +850,61 @@ void CIRRecordLowering::lowerUnion(bool 
nonVirtualBaseType) {
       fieldType = getStorageType(field);
     }
 
-    // This maps a field to its index. For unions, the index is always 0.
     fieldIdxMap[field->getCanonicalDecl()] = 0;
+    fieldTypes.push_back(fieldType);
+  }
 
-    // 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 ought 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;
-      }
-    }
+  // 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.
+  // Unlike classic codegen, we don't really 'give up' on adding all the 
fields,
+  // though this is a decision/implementation we might want to revisit.  We 
just
+  // fall back on the typical storage type calculation rather than this bizarre
+  // "choose the first thing", as that likely won't be compatible with later
+  // decisions.
+  for (const FieldDecl *field : recordDecl->fields()) {
 
-    // Because our union isn't zero initializable, we won't be getting a better
-    // storage type.
-    if (!zeroInitializable)
-      continue;
+    auto hasNamedMember = [](const FieldDecl *curField) -> bool {
+      const auto *rd = curField->getType()->getAsRecordDecl();
+      return rd && rd->findFirstNamedDataMember();
+    };
 
-    // 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.
-    //
-    // The base-subobject type instead uses a single (possibly clipped) storage
-    // type, mirroring classic CodeGen, so that it exposes the union's reusable
-    // tail padding.
-    if (!nonVirtualBaseType)
-      fieldTypes.push_back(fieldType);
+    if ((field->getIdentifier() || hasNamedMember(field)) &&
+        !isZeroInitializable(field)) {
+      zeroInitializable = zeroInitializableAsBase = false;
+    }
   }
 
-  if (!storageType) {
+  // If we have no candidates for storage, we are JUST padding.
+  if (fieldTypes.empty()) {
     appendPaddingBytes(layoutSize);
     return;
   }
 
+  mlir::Type storageType =
+      cir::UnionType::getUnionStorageType(dataLayout.layout, fieldTypes);
+
+  // If our storage size was bigger than our required size (can happen in the
+  // case of packed bitfields on Itanium) then just use an I8 array.
   if (layoutSize < getSize(storageType))
     storageType = getByteArrayType(layoutSize);
 
+  // The base-subobject record is built as a struct from fieldTypes, so add
+  // the storage type and any trailing padding as ordinary fields rather than
+  // routing padding through the union's single tail-padding slot.
   if (nonVirtualBaseType) {
-    // The base-subobject record is built as a struct from fieldTypes, so add
-    // the storage type and any trailing padding as ordinary fields rather than
-    // routing padding through the union's single tail-padding slot.
+    fieldTypes.clear();
----------------
andykaylor wrote:

I don't understand why we only want the storage type in this case.

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

Reply via email to