@@ -344,6 +344,51 @@ CIRGenFunction::buildCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E,
344
344
/* IsArrow=*/ false , E->getArg (0 ));
345
345
}
346
346
347
+ static void buildNullBaseClassInitialization (CIRGenFunction &CGF,
348
+ Address DestPtr,
349
+ const CXXRecordDecl *Base) {
350
+ if (Base->isEmpty ())
351
+ return ;
352
+
353
+ DestPtr = DestPtr.withElementType (CGF.UInt8Ty );
354
+
355
+ const ASTRecordLayout &Layout = CGF.getContext ().getASTRecordLayout (Base);
356
+ CharUnits NVSize = Layout.getNonVirtualSize ();
357
+
358
+ // We cannot simply zero-initialize the entire base sub-object if vbptrs are
359
+ // present, they are initialized by the most derived class before calling the
360
+ // constructor.
361
+ SmallVector<std::pair<CharUnits, CharUnits>, 1 > Stores;
362
+ Stores.emplace_back (CharUnits::Zero (), NVSize);
363
+
364
+ // Each store is split by the existence of a vbptr.
365
+ CharUnits VBPtrWidth = CGF.getPointerSize ();
366
+ std::vector<CharUnits> VBPtrOffsets =
367
+ CGF.CGM .getCXXABI ().getVBPtrOffsets (Base);
368
+ for (CharUnits VBPtrOffset : VBPtrOffsets) {
369
+ // Stop before we hit any virtual base pointers located in virtual bases.
370
+ if (VBPtrOffset >= NVSize)
371
+ break ;
372
+ std::pair<CharUnits, CharUnits> LastStore = Stores.pop_back_val ();
373
+ CharUnits LastStoreOffset = LastStore.first ;
374
+ CharUnits LastStoreSize = LastStore.second ;
375
+
376
+ CharUnits SplitBeforeOffset = LastStoreOffset;
377
+ CharUnits SplitBeforeSize = VBPtrOffset - SplitBeforeOffset;
378
+ assert (!SplitBeforeSize.isNegative () && " negative store size!" );
379
+ if (!SplitBeforeSize.isZero ())
380
+ Stores.emplace_back (SplitBeforeOffset, SplitBeforeSize);
381
+
382
+ CharUnits SplitAfterOffset = VBPtrOffset + VBPtrWidth;
383
+ CharUnits SplitAfterSize = LastStoreSize - SplitAfterOffset;
384
+ assert (!SplitAfterSize.isNegative () && " negative store size!" );
385
+ if (!SplitAfterSize.isZero ())
386
+ Stores.emplace_back (SplitAfterOffset, SplitAfterSize);
387
+ }
388
+
389
+ llvm_unreachable (" NYI" );
390
+ }
391
+
347
392
void CIRGenFunction::buildCXXConstructExpr (const CXXConstructExpr *E,
348
393
AggValueSlot Dest) {
349
394
assert (!Dest.isIgnored () && " Must have a destination!" );
@@ -362,7 +407,8 @@ void CIRGenFunction::buildCXXConstructExpr(const CXXConstructExpr *E,
362
407
break ;
363
408
case CXXConstructionKind::VirtualBase:
364
409
case CXXConstructionKind::NonVirtualBase:
365
- llvm_unreachable (" NYI" );
410
+ buildNullBaseClassInitialization (*this , Dest.getAddress (),
411
+ CD->getParent ());
366
412
break ;
367
413
}
368
414
}
0 commit comments