@@ -1451,6 +1451,7 @@ class ClangRecordLowering {
14511451 // / Place the next struct field at its appropriate offset.
14521452 void addStructField (const clang::FieldDecl *clangField,
14531453 VarDecl *swiftField, const clang::ASTRecordLayout &layout) {
1454+ bool isZeroSized = clangField->isZeroSize (ClangContext);
14541455 unsigned fieldOffset = layout.getFieldOffset (clangField->getFieldIndex ());
14551456 assert (!clangField->isBitField ());
14561457 Size offset ( SubobjectAdjustment.getValue () + fieldOffset / 8 );
@@ -1460,12 +1461,12 @@ class ClangRecordLowering {
14601461 auto &fieldTI = cast<FixedTypeInfo>(IGM.getTypeInfo (
14611462 SwiftType.getFieldType (swiftField, IGM.getSILModule (),
14621463 IGM.getMaximalTypeExpansionContext ())));
1463- addField (swiftField, offset, fieldTI);
1464+ addField (swiftField, offset, fieldTI, isZeroSized );
14641465 return ;
14651466 }
14661467
14671468 // Otherwise, add it as an opaque blob.
1468- auto fieldSize = ClangContext.getTypeSizeInChars (clangField->getType ());
1469+ auto fieldSize = isZeroSized ? clang::CharUnits::Zero () : ClangContext.getTypeSizeInChars (clangField->getType ());
14691470 return addOpaqueField (offset, Size (fieldSize.getQuantity ()));
14701471 }
14711472
@@ -1491,23 +1492,23 @@ class ClangRecordLowering {
14911492 if (fieldSize.isZero ()) return ;
14921493
14931494 auto &opaqueTI = IGM.getOpaqueStorageTypeInfo (fieldSize, Alignment (1 ));
1494- addField (nullptr , offset, opaqueTI);
1495+ addField (nullptr , offset, opaqueTI, false );
14951496 }
14961497
14971498 // / Add storage for an (optional) Swift field at the given offset.
14981499 void addField (VarDecl *swiftField, Size offset,
1499- const FixedTypeInfo &fieldType) {
1500- assert (offset >= NextOffset && " adding fields out of order" );
1500+ const FixedTypeInfo &fieldType, bool isZeroSized ) {
1501+ assert (isZeroSized || offset >= NextOffset && " adding fields out of order" );
15011502
15021503 // Add a padding field if required.
1503- if (offset != NextOffset)
1504+ if (!isZeroSized && offset != NextOffset)
15041505 addPaddingField (offset);
15051506
1506- addFieldInfo (swiftField, fieldType);
1507+ addFieldInfo (swiftField, fieldType, isZeroSized );
15071508 }
15081509
15091510 // / Add information to track a value field at the current offset.
1510- void addFieldInfo (VarDecl *swiftField, const FixedTypeInfo &fieldType) {
1511+ void addFieldInfo (VarDecl *swiftField, const FixedTypeInfo &fieldType, bool isZeroSized ) {
15111512 bool isLoadableField = isa<LoadableTypeInfo>(fieldType);
15121513 unsigned explosionSize = 0 ;
15131514 if (isLoadableField)
@@ -1517,11 +1518,15 @@ class ClangRecordLowering {
15171518 unsigned explosionEnd = NextExplosionIndex;
15181519
15191520 ElementLayout layout = ElementLayout::getIncomplete (fieldType);
1520- auto isEmpty = fieldType.isKnownEmpty (ResilienceExpansion::Maximal);
1521- if (isEmpty)
1522- layout.completeEmptyTailAllocatedCType (
1523- fieldType.isTriviallyDestroyable (ResilienceExpansion::Maximal), NextOffset);
1524- else
1521+ auto isEmpty = isZeroSized || fieldType.isKnownEmpty (ResilienceExpansion::Maximal);
1522+ if (isEmpty) {
1523+ if (isZeroSized)
1524+ layout.completeEmpty (
1525+ fieldType.isTriviallyDestroyable (ResilienceExpansion::Maximal), NextOffset);
1526+ else
1527+ layout.completeEmptyTailAllocatedCType (
1528+ fieldType.isTriviallyDestroyable (ResilienceExpansion::Maximal), NextOffset);
1529+ } else
15251530 layout.completeFixed (fieldType.isTriviallyDestroyable (ResilienceExpansion::Maximal),
15261531 NextOffset, LLVMFields.size ());
15271532
0 commit comments