================ @@ -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