@@ -354,7 +354,27 @@ namespace {
354354
355355 TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
356356 SILType T) const override {
357- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
357+ if (!IGM.getOptions ().ForceStructTypeLayouts ) {
358+ return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
359+ }
360+ if (!areFieldsABIAccessible ()) {
361+ return IGM.typeLayoutCache .getOrCreateResilientEntry (T);
362+ }
363+
364+ std::vector<TypeLayoutEntry *> fields;
365+ for (auto &field : getFields ()) {
366+ auto fieldTy = field.getType (IGM, T);
367+ fields.push_back (
368+ field.getTypeInfo ().buildTypeLayoutEntry (IGM, fieldTy));
369+ }
370+ assert (!fields.empty () &&
371+ " Empty structs should not be LoadableClangRecordTypeInfo" );
372+
373+ if (fields.size () == 1 ) {
374+ return fields[0 ];
375+ }
376+
377+ return IGM.typeLayoutCache .getOrCreateAlignedGroupEntry (fields, 1 );
358378 }
359379
360380 void initializeFromParams (IRGenFunction &IGF, Explosion ¶ms,
@@ -520,7 +540,25 @@ namespace {
520540
521541 TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
522542 SILType T) const override {
523- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
543+ if (!IGM.getOptions ().ForceStructTypeLayouts || getCXXDestructor (T) ||
544+ !areFieldsABIAccessible ()) {
545+ return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
546+ }
547+
548+ std::vector<TypeLayoutEntry *> fields;
549+ for (auto &field : getFields ()) {
550+ auto fieldTy = field.getType (IGM, T);
551+ fields.push_back (
552+ field.getTypeInfo ().buildTypeLayoutEntry (IGM, fieldTy));
553+ }
554+ assert (!fields.empty () &&
555+ " Empty structs should not be AddressOnlyRecordTypeInfo" );
556+
557+ if (fields.size () == 1 ) {
558+ return fields[0 ];
559+ }
560+
561+ return IGM.typeLayoutCache .getOrCreateAlignedGroupEntry (fields, 1 );
524562 }
525563
526564 void initializeFromParams (IRGenFunction &IGF, Explosion ¶ms,
@@ -583,7 +621,30 @@ namespace {
583621
584622 TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
585623 SILType T) const override {
586- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
624+ if (!IGM.getOptions ().ForceStructTypeLayouts ) {
625+ return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
626+ }
627+
628+ if (!areFieldsABIAccessible ()) {
629+ return IGM.typeLayoutCache .getOrCreateResilientEntry (T);
630+ }
631+
632+ if (getFields ().empty ()) {
633+ return IGM.typeLayoutCache .getEmptyEntry ();
634+ }
635+
636+ std::vector<TypeLayoutEntry *> fields;
637+ for (auto &field : getFields ()) {
638+ auto fieldTy = field.getType (IGM, T);
639+ fields.push_back (
640+ field.getTypeInfo ().buildTypeLayoutEntry (IGM, fieldTy));
641+ }
642+
643+ if (fields.size () == 1 ) {
644+ return fields[0 ];
645+ }
646+
647+ return IGM.typeLayoutCache .getOrCreateAlignedGroupEntry (fields, 1 );
587648 }
588649
589650 void initializeFromParams (IRGenFunction &IGF, Explosion ¶ms,
@@ -622,7 +683,28 @@ namespace {
622683
623684 TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
624685 SILType T) const override {
625- return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
686+ if (!IGM.getOptions ().ForceStructTypeLayouts ) {
687+ return IGM.typeLayoutCache .getOrCreateScalarEntry (*this , T);
688+ }
689+
690+ if (!areFieldsABIAccessible ()) {
691+ return IGM.typeLayoutCache .getOrCreateResilientEntry (T);
692+ }
693+
694+ std::vector<TypeLayoutEntry *> fields;
695+ for (auto &field : getFields ()) {
696+ auto fieldTy = field.getType (IGM, T);
697+ fields.push_back (
698+ field.getTypeInfo ().buildTypeLayoutEntry (IGM, fieldTy));
699+ }
700+ assert (!fields.empty () &&
701+ " Empty structs should not be FixedStructTypeInfo" );
702+
703+ if (fields.size () == 1 ) {
704+ return fields[0 ];
705+ }
706+
707+ return IGM.typeLayoutCache .getOrCreateAlignedGroupEntry (fields, 1 );
626708 }
627709
628710 llvm::NoneType getNonFixedOffsets (IRGenFunction &IGF) const {
@@ -708,7 +790,7 @@ namespace {
708790 return fields[0 ];
709791 }
710792
711- return IGM.typeLayoutCache .getOrCreateAlignedGroupEntry (fields, 1 , false );
793+ return IGM.typeLayoutCache .getOrCreateAlignedGroupEntry (fields, 1 );
712794 }
713795
714796 // We have an indirect schema.
0 commit comments