@@ -43,6 +43,19 @@ using namespace clang::CIRGen;
4343namespace {
4444class ConstExprEmitter ;
4545
46+ static mlir::TypedAttr computePadding (CIRGenModule &CGM, CharUnits size) {
47+ auto eltTy = CGM.UCharTy ;
48+ auto arSize = size.getQuantity ();
49+ auto &bld = CGM.getBuilder ();
50+ if (size > CharUnits::One ()) {
51+ SmallVector<mlir::Attribute, 4 > elts (arSize, bld.getZeroAttr (eltTy));
52+ return bld.getConstArray (mlir::ArrayAttr::get (bld.getContext (), elts),
53+ bld.getArrayType (eltTy, arSize));
54+ } else {
55+ return cir::ZeroAttr::get (bld.getContext (), eltTy);
56+ }
57+ }
58+
4659static mlir::Attribute
4760emitArrayConstant (CIRGenModule &CGM, mlir::Type DesiredType,
4861 mlir::Type CommonElementType, unsigned ArrayBound,
@@ -70,12 +83,7 @@ struct ConstantAggregateBuilderUtils {
7083 }
7184
7285 mlir::TypedAttr getPadding (CharUnits size) const {
73- auto eltTy = CGM.UCharTy ;
74- auto arSize = size.getQuantity ();
75- auto &bld = CGM.getBuilder ();
76- SmallVector<mlir::Attribute, 4 > elts (arSize, bld.getZeroAttr (eltTy));
77- return bld.getConstArray (mlir::ArrayAttr::get (bld.getContext (), elts),
78- bld.getArrayType (eltTy, arSize));
86+ return computePadding (CGM, size);
7987 }
8088
8189 mlir::Attribute getZeroes (CharUnits ZeroSize) const {
@@ -508,6 +516,11 @@ class ConstStructBuilder {
508516 bool Build (InitListExpr *ILE, bool AllowOverwrite);
509517 bool Build (const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase,
510518 const CXXRecordDecl *VTableClass, CharUnits BaseOffset);
519+
520+ bool ApplyZeroInitPadding (const ASTRecordLayout &Layout, unsigned FieldNo,
521+ const FieldDecl &Field, bool AllowOverwrite,
522+ CharUnits &SizeSoFar, bool &ZeroFieldSize);
523+
511524 mlir::Attribute Finalize (QualType Ty);
512525};
513526
@@ -614,6 +627,10 @@ bool ConstStructBuilder::Build(InitListExpr *ILE, bool AllowOverwrite) {
614627 if (CXXRD->getNumBases ())
615628 return false ;
616629
630+ const bool ZeroInitPadding = CGM.shouldZeroInitPadding ();
631+ bool ZeroFieldSize = false ;
632+ CharUnits SizeSoFar = CharUnits::Zero ();
633+
617634 for (FieldDecl *Field : RD->fields ()) {
618635 ++FieldNo;
619636
@@ -642,6 +659,11 @@ bool ConstStructBuilder::Build(InitListExpr *ILE, bool AllowOverwrite) {
642659 continue ;
643660 }
644661
662+ if (ZeroInitPadding &&
663+ !ApplyZeroInitPadding (Layout, FieldNo, *Field, AllowOverwrite,
664+ SizeSoFar, ZeroFieldSize))
665+ return false ;
666+
645667 // When emitting a DesignatedInitUpdateExpr, a nested InitListExpr
646668 // represents additional overwriting of our current constant value, and not
647669 // a new constant to emit independently.
@@ -784,6 +806,38 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
784806 return true ;
785807}
786808
809+ bool ConstStructBuilder::ApplyZeroInitPadding (
810+ const ASTRecordLayout &Layout, unsigned FieldNo, const FieldDecl &Field,
811+ bool AllowOverwrite, CharUnits &SizeSoFar, bool &ZeroFieldSize) {
812+
813+ uint64_t StartBitOffset = Layout.getFieldOffset (FieldNo);
814+ CharUnits StartOffset =
815+ CGM.getASTContext ().toCharUnitsFromBits (StartBitOffset);
816+ if (SizeSoFar < StartOffset) {
817+ if (!AppendBytes (SizeSoFar, computePadding (CGM, StartOffset - SizeSoFar),
818+ AllowOverwrite))
819+ return false ;
820+ }
821+
822+ if (!Field.isBitField ()) {
823+ CharUnits FieldSize =
824+ CGM.getASTContext ().getTypeSizeInChars (Field.getType ());
825+ SizeSoFar = StartOffset + FieldSize;
826+ ZeroFieldSize = FieldSize.isZero ();
827+ } else {
828+ const CIRGenRecordLayout &RL =
829+ CGM.getTypes ().getCIRGenRecordLayout (Field.getParent ());
830+ const CIRGenBitFieldInfo &Info = RL.getBitFieldInfo (&Field);
831+ uint64_t EndBitOffset = StartBitOffset + Info.Size ;
832+ SizeSoFar = CGM.getASTContext ().toCharUnitsFromBits (EndBitOffset);
833+ if (EndBitOffset % CGM.getASTContext ().getCharWidth () != 0 ) {
834+ SizeSoFar++;
835+ }
836+ ZeroFieldSize = Info.Size == 0 ;
837+ }
838+ return true ;
839+ }
840+
787841mlir::Attribute ConstStructBuilder::Finalize (QualType Type) {
788842 Type = Type.getNonReferenceType ();
789843 RecordDecl *RD = Type->castAs <RecordType>()->getDecl ();
0 commit comments