@@ -43,6 +43,19 @@ using namespace clang::CIRGen;
43
43
namespace {
44
44
class ConstExprEmitter ;
45
45
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
+
46
59
static mlir::Attribute
47
60
emitArrayConstant (CIRGenModule &CGM, mlir::Type DesiredType,
48
61
mlir::Type CommonElementType, unsigned ArrayBound,
@@ -70,12 +83,7 @@ struct ConstantAggregateBuilderUtils {
70
83
}
71
84
72
85
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);
79
87
}
80
88
81
89
mlir::Attribute getZeroes (CharUnits ZeroSize) const {
@@ -508,6 +516,11 @@ class ConstStructBuilder {
508
516
bool Build (InitListExpr *ILE, bool AllowOverwrite);
509
517
bool Build (const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase,
510
518
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
+
511
524
mlir::Attribute Finalize (QualType Ty);
512
525
};
513
526
@@ -614,6 +627,10 @@ bool ConstStructBuilder::Build(InitListExpr *ILE, bool AllowOverwrite) {
614
627
if (CXXRD->getNumBases ())
615
628
return false ;
616
629
630
+ const bool ZeroInitPadding = CGM.shouldZeroInitPadding ();
631
+ bool ZeroFieldSize = false ;
632
+ CharUnits SizeSoFar = CharUnits::Zero ();
633
+
617
634
for (FieldDecl *Field : RD->fields ()) {
618
635
++FieldNo;
619
636
@@ -642,6 +659,11 @@ bool ConstStructBuilder::Build(InitListExpr *ILE, bool AllowOverwrite) {
642
659
continue ;
643
660
}
644
661
662
+ if (ZeroInitPadding &&
663
+ !ApplyZeroInitPadding (Layout, FieldNo, *Field, AllowOverwrite,
664
+ SizeSoFar, ZeroFieldSize))
665
+ return false ;
666
+
645
667
// When emitting a DesignatedInitUpdateExpr, a nested InitListExpr
646
668
// represents additional overwriting of our current constant value, and not
647
669
// a new constant to emit independently.
@@ -784,6 +806,38 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
784
806
return true ;
785
807
}
786
808
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
+
787
841
mlir::Attribute ConstStructBuilder::Finalize (QualType Type) {
788
842
Type = Type.getNonReferenceType ();
789
843
RecordDecl *RD = Type->castAs <RecordType>()->getDecl ();
0 commit comments