@@ -354,37 +354,6 @@ namespace {
354
354
}
355
355
}
356
356
357
- template <class Fn >
358
- void forEachNonEmptyBaseTypeInfo (Fn fn) const {
359
- forEachNonEmptyBase ([&](clang::QualType, clang::CharUnits,
360
- clang::CharUnits size) {
361
- auto &typeInfo = IGM.getOpaqueStorageTypeInfo (Size (size.getQuantity ()),
362
- Alignment (1 ));
363
- fn (typeInfo);
364
- });
365
- }
366
-
367
- template <class Fn >
368
- void forEachNonEmptyBaseTypeInfoAndBaseAddress (IRGenFunction &IGF,
369
- Address addr, Fn fn) const {
370
- forEachNonEmptyBase ([&](clang::QualType,
371
- clang::CharUnits offset, clang::CharUnits size) {
372
- auto &typeInfo = IGM.getOpaqueStorageTypeInfo (Size (size.getQuantity ()),
373
- Alignment (1 ));
374
-
375
- Address baseAddr = addr;
376
- if (offset.getQuantity () != 0 ) {
377
- auto baseAddrVal =
378
- IGF.Builder .CreateBitCast (addr.getAddress (), IGF.IGM .Int8PtrTy );
379
- baseAddrVal = IGF.Builder .CreateConstGEP1_64 (
380
- IGF.IGM .Int8Ty , baseAddrVal, offset.getQuantity ());
381
- baseAddr = Address (baseAddrVal, Alignment (1 ));
382
- }
383
-
384
- fn (typeInfo, baseAddr);
385
- });
386
- }
387
-
388
357
public:
389
358
LoadableClangRecordTypeInfo (ArrayRef<ClangFieldInfo> fields,
390
359
unsigned explosionSize, IRGenModule &IGM,
@@ -437,106 +406,6 @@ namespace {
437
406
lowering.addTypedData (ClangDecl, offset.asCharUnits ());
438
407
}
439
408
440
- void getSchema (ExplosionSchema &schema) const override {
441
- forEachNonEmptyBaseTypeInfo ([&](const LoadableTypeInfo &typeInfo) {
442
- typeInfo.getSchema (schema);
443
- });
444
-
445
- for (auto &field : getFields ()) {
446
- field.getTypeInfo ().getSchema (schema);
447
- }
448
- }
449
-
450
- void projectFieldFromExplosion (IRGenFunction &IGF, Explosion &in,
451
- VarDecl *field,
452
- Explosion &out) const override {
453
- auto &fieldInfo = getFieldInfo (field);
454
-
455
- // If the field requires no storage, there's nothing to do.
456
- if (fieldInfo.isEmpty ())
457
- return ;
458
-
459
- unsigned baseOffset = 0 ;
460
- if (auto cxxRecord = dyn_cast<clang::CXXRecordDecl>(ClangDecl)) {
461
- baseOffset = llvm::count_if (cxxRecord->bases (), [](auto base) {
462
- auto baseType = base.getType ().getCanonicalType ();
463
-
464
- auto baseRecord = cast<clang::RecordType>(baseType)->getDecl ();
465
- auto baseCxxRecord = cast<clang::CXXRecordDecl>(baseRecord);
466
-
467
- return !baseCxxRecord->isEmpty ();
468
- });
469
- }
470
-
471
- // Otherwise, project from the base.
472
- auto fieldRange = fieldInfo.getProjectionRange ();
473
- auto elements = in.getRange (fieldRange.first + baseOffset,
474
- fieldRange.second + baseOffset);
475
- out.add (elements);
476
- }
477
-
478
- void reexplode (IRGenFunction &IGF, Explosion &src,
479
- Explosion &dest) const override {
480
- forEachNonEmptyBaseTypeInfo ([&](const LoadableTypeInfo &typeInfo) {
481
- typeInfo.reexplode (IGF, src, dest);
482
- });
483
-
484
- for (auto &field : getFields ()) {
485
- cast<LoadableTypeInfo>(field.getTypeInfo ()).reexplode (IGF, src, dest);
486
- }
487
- }
488
-
489
- void initialize (IRGenFunction &IGF, Explosion &e, Address addr,
490
- bool isOutlined) const override {
491
- forEachNonEmptyBaseTypeInfoAndBaseAddress (
492
- IGF, addr, [&](const LoadableTypeInfo &typeInfo, Address baseAddr) {
493
- typeInfo.initialize (IGF, e, baseAddr, isOutlined);
494
- });
495
-
496
- for (auto &field : getFields ()) {
497
- if (field.isEmpty ())
498
- continue ;
499
-
500
- Address fieldAddr = field.projectAddress (IGF, addr, None);
501
- cast<LoadableTypeInfo>(field.getTypeInfo ())
502
- .initialize (IGF, e, fieldAddr, isOutlined);
503
- }
504
- }
505
-
506
- void loadAsTake (IRGenFunction &IGF, Address addr,
507
- Explosion &e) const override {
508
- forEachNonEmptyBaseTypeInfoAndBaseAddress (
509
- IGF, addr, [&](const LoadableTypeInfo &typeInfo, Address baseAddr) {
510
- typeInfo.loadAsTake (IGF, baseAddr, e);
511
- });
512
-
513
- for (auto &field : getFields ()) {
514
- if (field.isEmpty ())
515
- continue ;
516
-
517
- Address fieldAddr = field.projectAddress (IGF, addr, None);
518
- cast<LoadableTypeInfo>(field.getTypeInfo ())
519
- .loadAsTake (IGF, fieldAddr, e);
520
- }
521
- }
522
-
523
- void loadAsCopy (IRGenFunction &IGF, Address addr,
524
- Explosion &e) const override {
525
- forEachNonEmptyBaseTypeInfoAndBaseAddress (
526
- IGF, addr, [&](const LoadableTypeInfo &typeInfo, Address baseAddr) {
527
- typeInfo.loadAsCopy (IGF, baseAddr, e);
528
- });
529
-
530
- for (auto &field : getFields ()) {
531
- if (field.isEmpty ())
532
- continue ;
533
-
534
- Address fieldAddr = field.projectAddress (IGF, addr, None);
535
- cast<LoadableTypeInfo>(field.getTypeInfo ())
536
- .loadAsCopy (IGF, fieldAddr, e);
537
- }
538
- }
539
-
540
409
llvm::NoneType getNonFixedOffsets (IRGenFunction &IGF) const {
541
410
return None;
542
411
}
@@ -1168,6 +1037,7 @@ class ClangRecordLowering {
1168
1037
if (ClangDecl->isUnion ()) {
1169
1038
collectUnionFields ();
1170
1039
} else {
1040
+ collectBases ();
1171
1041
collectStructFields ();
1172
1042
}
1173
1043
}
@@ -1195,6 +1065,29 @@ class ClangRecordLowering {
1195
1065
return (swiftField->getClangNode ().castAsDecl () == clangField);
1196
1066
}
1197
1067
1068
+ void collectBases () {
1069
+ auto &layout = ClangDecl->getASTContext ().getASTRecordLayout (ClangDecl);
1070
+
1071
+ if (auto cxxRecord = dyn_cast<clang::CXXRecordDecl>(ClangDecl)) {
1072
+ for (auto base : cxxRecord->bases ()) {
1073
+ if (base.isVirtual ())
1074
+ continue ;
1075
+
1076
+ auto baseType = base.getType ().getCanonicalType ();
1077
+
1078
+ auto baseRecord = cast<clang::RecordType>(baseType)->getDecl ();
1079
+ auto baseCxxRecord = cast<clang::CXXRecordDecl>(baseRecord);
1080
+
1081
+ if (baseCxxRecord->isEmpty ())
1082
+ continue ;
1083
+
1084
+ auto offset = layout.getBaseClassOffset (baseCxxRecord);
1085
+ auto size = ClangDecl->getASTContext ().getTypeSizeInChars (baseType);
1086
+ addOpaqueField (Size (offset.getQuantity ()), Size (size.getQuantity ()));
1087
+ }
1088
+ }
1089
+ }
1090
+
1198
1091
void collectStructFields () {
1199
1092
auto cfi = ClangDecl->field_begin (), cfe = ClangDecl->field_end ();
1200
1093
auto swiftProperties = SwiftDecl->getStoredProperties ();
0 commit comments