@@ -1451,6 +1451,7 @@ class ClangRecordLowering {
1451
1451
// / Place the next struct field at its appropriate offset.
1452
1452
void addStructField (const clang::FieldDecl *clangField,
1453
1453
VarDecl *swiftField, const clang::ASTRecordLayout &layout) {
1454
+ bool isZeroSized = clangField->isZeroSize (ClangContext);
1454
1455
unsigned fieldOffset = layout.getFieldOffset (clangField->getFieldIndex ());
1455
1456
assert (!clangField->isBitField ());
1456
1457
Size offset ( SubobjectAdjustment.getValue () + fieldOffset / 8 );
@@ -1460,12 +1461,12 @@ class ClangRecordLowering {
1460
1461
auto &fieldTI = cast<FixedTypeInfo>(IGM.getTypeInfo (
1461
1462
SwiftType.getFieldType (swiftField, IGM.getSILModule (),
1462
1463
IGM.getMaximalTypeExpansionContext ())));
1463
- addField (swiftField, offset, fieldTI);
1464
+ addField (swiftField, offset, fieldTI, isZeroSized );
1464
1465
return ;
1465
1466
}
1466
1467
1467
1468
// 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 ());
1469
1470
return addOpaqueField (offset, Size (fieldSize.getQuantity ()));
1470
1471
}
1471
1472
@@ -1491,23 +1492,23 @@ class ClangRecordLowering {
1491
1492
if (fieldSize.isZero ()) return ;
1492
1493
1493
1494
auto &opaqueTI = IGM.getOpaqueStorageTypeInfo (fieldSize, Alignment (1 ));
1494
- addField (nullptr , offset, opaqueTI);
1495
+ addField (nullptr , offset, opaqueTI, false );
1495
1496
}
1496
1497
1497
1498
// / Add storage for an (optional) Swift field at the given offset.
1498
1499
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" );
1501
1502
1502
1503
// Add a padding field if required.
1503
- if (offset != NextOffset)
1504
+ if (!isZeroSized && offset != NextOffset)
1504
1505
addPaddingField (offset);
1505
1506
1506
- addFieldInfo (swiftField, fieldType);
1507
+ addFieldInfo (swiftField, fieldType, isZeroSized );
1507
1508
}
1508
1509
1509
1510
// / 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 ) {
1511
1512
bool isLoadableField = isa<LoadableTypeInfo>(fieldType);
1512
1513
unsigned explosionSize = 0 ;
1513
1514
if (isLoadableField)
@@ -1517,11 +1518,15 @@ class ClangRecordLowering {
1517
1518
unsigned explosionEnd = NextExplosionIndex;
1518
1519
1519
1520
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
1525
1530
layout.completeFixed (fieldType.isTriviallyDestroyable (ResilienceExpansion::Maximal),
1526
1531
NextOffset, LLVMFields.size ());
1527
1532
0 commit comments