@@ -354,7 +354,27 @@ namespace {
354
354
355
355
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
356
356
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 );
358
378
}
359
379
360
380
void initializeFromParams (IRGenFunction &IGF, Explosion ¶ms,
@@ -520,7 +540,25 @@ namespace {
520
540
521
541
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
522
542
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 );
524
562
}
525
563
526
564
void initializeFromParams (IRGenFunction &IGF, Explosion ¶ms,
@@ -583,7 +621,30 @@ namespace {
583
621
584
622
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
585
623
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 );
587
648
}
588
649
589
650
void initializeFromParams (IRGenFunction &IGF, Explosion ¶ms,
@@ -622,7 +683,28 @@ namespace {
622
683
623
684
TypeLayoutEntry *buildTypeLayoutEntry (IRGenModule &IGM,
624
685
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 );
626
708
}
627
709
628
710
llvm::NoneType getNonFixedOffsets (IRGenFunction &IGF) const {
@@ -708,7 +790,7 @@ namespace {
708
790
return fields[0 ];
709
791
}
710
792
711
- return IGM.typeLayoutCache .getOrCreateAlignedGroupEntry (fields, 1 , false );
793
+ return IGM.typeLayoutCache .getOrCreateAlignedGroupEntry (fields, 1 );
712
794
}
713
795
714
796
// We have an indirect schema.
0 commit comments