@@ -1002,7 +1002,6 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
1002
1002
// Add name if not anonymous or intermediate type.
1003
1003
StringRef Name = CTy->getName ();
1004
1004
1005
- uint64_t Size = CTy->getSizeInBits () >> 3 ;
1006
1005
uint16_t Tag = Buffer.getTag ();
1007
1006
1008
1007
switch (Tag) {
@@ -1165,15 +1164,29 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
1165
1164
if (Tag == dwarf::DW_TAG_enumeration_type ||
1166
1165
Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type ||
1167
1166
Tag == dwarf::DW_TAG_union_type) {
1168
- // Add size if non-zero (derived types might be zero-sized.)
1169
- // Ignore the size if it's a non-enum forward decl.
1170
- // TODO: Do we care about size for enum forward declarations?
1171
- if (Size &&
1172
- (!CTy->isForwardDecl () || Tag == dwarf::DW_TAG_enumeration_type))
1173
- addUInt (Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);
1174
- else if (!CTy->isForwardDecl ())
1175
- // Add zero size if it is not a forward declaration.
1176
- addUInt (Buffer, dwarf::DW_AT_byte_size, std::nullopt, 0 );
1167
+ if (auto *Var = dyn_cast_or_null<DIVariable>(CTy->getRawSizeInBits ())) {
1168
+ if (auto *VarDIE = getDIE (Var)) {
1169
+ addDIEEntry (Buffer, dwarf::DW_AT_bit_size, *VarDIE);
1170
+ }
1171
+ } else if (auto *Exp =
1172
+ dyn_cast_or_null<DIExpression>(CTy->getRawSizeInBits ())) {
1173
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
1174
+ DIEDwarfExpression DwarfExpr (*Asm, getCU (), *Loc);
1175
+ DwarfExpr.setMemoryLocationKind ();
1176
+ DwarfExpr.addExpression (Exp);
1177
+ addBlock (Buffer, dwarf::DW_AT_bit_size, DwarfExpr.finalize ());
1178
+ } else {
1179
+ uint64_t Size = CTy->getSizeInBits () >> 3 ;
1180
+ // Add size if non-zero (derived types might be zero-sized.)
1181
+ // Ignore the size if it's a non-enum forward decl.
1182
+ // TODO: Do we care about size for enum forward declarations?
1183
+ if (Size &&
1184
+ (!CTy->isForwardDecl () || Tag == dwarf::DW_TAG_enumeration_type))
1185
+ addUInt (Buffer, dwarf::DW_AT_byte_size, std::nullopt, Size);
1186
+ else if (!CTy->isForwardDecl ())
1187
+ // Add zero size if it is not a forward declaration.
1188
+ addUInt (Buffer, dwarf::DW_AT_byte_size, std::nullopt, 0 );
1189
+ }
1177
1190
1178
1191
// If we're a forward decl, say so.
1179
1192
if (CTy->isForwardDecl ())
@@ -1840,74 +1853,119 @@ DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
1840
1853
1841
1854
addBlock (MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie);
1842
1855
} else {
1843
- uint64_t Size = DT->getSizeInBits ();
1844
- uint64_t FieldSize = DD->getBaseTypeSize (DT);
1845
- uint32_t AlignInBytes = DT->getAlignInBytes ();
1846
- uint64_t OffsetInBytes;
1856
+ uint64_t Size = 0 ;
1857
+ uint64_t FieldSize = 0 ;
1847
1858
1848
1859
bool IsBitfield = DT->isBitField ();
1849
- if (IsBitfield) {
1850
- // Handle bitfield, assume bytes are 8 bits.
1851
- if (DD->useDWARF2Bitfields ())
1852
- addUInt (MemberDie, dwarf::DW_AT_byte_size, std::nullopt, FieldSize / 8 );
1853
- addUInt (MemberDie, dwarf::DW_AT_bit_size, std::nullopt, Size);
1854
-
1855
- assert (DT->getOffsetInBits () <=
1856
- (uint64_t )std::numeric_limits<int64_t >::max ());
1857
- int64_t Offset = DT->getOffsetInBits ();
1858
- // We can't use DT->getAlignInBits() here: AlignInBits for member type
1859
- // is non-zero if and only if alignment was forced (e.g. _Alignas()),
1860
- // which can't be done with bitfields. Thus we use FieldSize here.
1861
- uint32_t AlignInBits = FieldSize;
1862
- uint32_t AlignMask = ~(AlignInBits - 1 );
1863
- // The bits from the start of the storage unit to the start of the field.
1864
- uint64_t StartBitOffset = Offset - (Offset & AlignMask);
1865
- // The byte offset of the field's aligned storage unit inside the struct.
1866
- OffsetInBytes = (Offset - StartBitOffset) / 8 ;
1867
-
1868
- if (DD->useDWARF2Bitfields ()) {
1869
- uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1870
- uint64_t FieldOffset = (HiMark - FieldSize);
1871
- Offset -= FieldOffset;
1872
-
1873
- // Maybe we need to work from the other end.
1874
- if (Asm->getDataLayout ().isLittleEndian ())
1875
- Offset = FieldSize - (Offset + Size);
1876
-
1877
- if (Offset < 0 )
1878
- addSInt (MemberDie, dwarf::DW_AT_bit_offset, dwarf::DW_FORM_sdata,
1879
- Offset);
1880
- else
1881
- addUInt (MemberDie, dwarf::DW_AT_bit_offset, std::nullopt,
1882
- (uint64_t )Offset);
1883
- OffsetInBytes = FieldOffset >> 3 ;
1884
- } else {
1885
- addUInt (MemberDie, dwarf::DW_AT_data_bit_offset, std::nullopt, Offset);
1860
+
1861
+ // Handle the size.
1862
+ if (auto *Var = dyn_cast_or_null<DIVariable>(DT->getRawSizeInBits ())) {
1863
+ if (auto *VarDIE = getDIE (Var)) {
1864
+ addDIEEntry (MemberDie, dwarf::DW_AT_bit_size, *VarDIE);
1886
1865
}
1866
+ } else if (auto *Exp =
1867
+ dyn_cast_or_null<DIExpression>(DT->getRawSizeInBits ())) {
1868
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
1869
+ DIEDwarfExpression DwarfExpr (*Asm, getCU (), *Loc);
1870
+ DwarfExpr.setMemoryLocationKind ();
1871
+ DwarfExpr.addExpression (Exp);
1872
+ addBlock (MemberDie, dwarf::DW_AT_bit_size, DwarfExpr.finalize ());
1887
1873
} else {
1888
- // This is not a bitfield.
1889
- OffsetInBytes = DT->getOffsetInBits () / 8 ;
1890
- if (AlignInBytes)
1891
- addUInt (MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1892
- AlignInBytes);
1874
+ Size = DT->getSizeInBits ();
1875
+ FieldSize = DD->getBaseTypeSize (DT);
1876
+ if (IsBitfield) {
1877
+ // Handle bitfield, assume bytes are 8 bits.
1878
+ if (DD->useDWARF2Bitfields ())
1879
+ addUInt (MemberDie, dwarf::DW_AT_byte_size, std::nullopt,
1880
+ FieldSize / 8 );
1881
+ addUInt (MemberDie, dwarf::DW_AT_bit_size, std::nullopt, Size);
1882
+ }
1893
1883
}
1894
1884
1895
- if (DD->getDwarfVersion () <= 2 ) {
1896
- DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc;
1897
- addUInt (*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
1898
- addUInt (*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
1899
- addBlock (MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
1900
- } else if (!IsBitfield || DD->useDWARF2Bitfields ()) {
1901
- // In DWARF v3, DW_FORM_data4/8 in DW_AT_data_member_location are
1902
- // interpreted as location-list pointers. Interpreting constants as
1903
- // pointers is not expected, so we use DW_FORM_udata to encode the
1904
- // constants here.
1905
- if (DD->getDwarfVersion () == 3 )
1906
- addUInt (MemberDie, dwarf::DW_AT_data_member_location,
1907
- dwarf::DW_FORM_udata, OffsetInBytes);
1908
- else
1909
- addUInt (MemberDie, dwarf::DW_AT_data_member_location, std::nullopt,
1910
- OffsetInBytes);
1885
+ // Handle the location. DW_AT_data_bit_offset won't allow an
1886
+ // expression until DWARF 6, but it can be used as an extension.
1887
+ // See https://dwarfstd.org/issues/250501.1.html
1888
+ if (auto *Var = dyn_cast_or_null<DIVariable>(DT->getRawOffsetInBits ())) {
1889
+ if (!Asm->TM .Options .DebugStrictDwarf || DD->getDwarfVersion () >= 6 ) {
1890
+ if (auto *VarDIE = getDIE (Var)) {
1891
+ addDIEEntry (MemberDie, dwarf::DW_AT_data_bit_offset, *VarDIE);
1892
+ }
1893
+ }
1894
+ } else if (auto *Expr =
1895
+ dyn_cast_or_null<DIExpression>(DT->getRawOffsetInBits ())) {
1896
+ if (!Asm->TM .Options .DebugStrictDwarf || DD->getDwarfVersion () >= 6 ) {
1897
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
1898
+ DIEDwarfExpression DwarfExpr (*Asm, getCU (), *Loc);
1899
+ DwarfExpr.setMemoryLocationKind ();
1900
+ DwarfExpr.addExpression (Expr);
1901
+ addBlock (MemberDie, dwarf::DW_AT_data_bit_offset, DwarfExpr.finalize ());
1902
+ }
1903
+ } else {
1904
+ uint32_t AlignInBytes = DT->getAlignInBytes ();
1905
+ uint64_t OffsetInBytes;
1906
+
1907
+ if (IsBitfield) {
1908
+ assert (DT->getOffsetInBits () <=
1909
+ (uint64_t )std::numeric_limits<int64_t >::max ());
1910
+ int64_t Offset = DT->getOffsetInBits ();
1911
+ // We can't use DT->getAlignInBits() here: AlignInBits for member type
1912
+ // is non-zero if and only if alignment was forced (e.g. _Alignas()),
1913
+ // which can't be done with bitfields. Thus we use FieldSize here.
1914
+ uint32_t AlignInBits = FieldSize;
1915
+ uint32_t AlignMask = ~(AlignInBits - 1 );
1916
+ // The bits from the start of the storage unit to the start of the
1917
+ // field.
1918
+ uint64_t StartBitOffset = Offset - (Offset & AlignMask);
1919
+ // The byte offset of the field's aligned storage unit inside the
1920
+ // struct.
1921
+ OffsetInBytes = (Offset - StartBitOffset) / 8 ;
1922
+
1923
+ if (DD->useDWARF2Bitfields ()) {
1924
+ uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1925
+ uint64_t FieldOffset = (HiMark - FieldSize);
1926
+ Offset -= FieldOffset;
1927
+
1928
+ // Maybe we need to work from the other end.
1929
+ if (Asm->getDataLayout ().isLittleEndian ())
1930
+ Offset = FieldSize - (Offset + Size);
1931
+
1932
+ if (Offset < 0 )
1933
+ addSInt (MemberDie, dwarf::DW_AT_bit_offset, dwarf::DW_FORM_sdata,
1934
+ Offset);
1935
+ else
1936
+ addUInt (MemberDie, dwarf::DW_AT_bit_offset, std::nullopt,
1937
+ (uint64_t )Offset);
1938
+ OffsetInBytes = FieldOffset >> 3 ;
1939
+ } else {
1940
+ addUInt (MemberDie, dwarf::DW_AT_data_bit_offset, std::nullopt,
1941
+ Offset);
1942
+ }
1943
+ } else {
1944
+ // This is not a bitfield.
1945
+ OffsetInBytes = DT->getOffsetInBits () / 8 ;
1946
+ if (AlignInBytes)
1947
+ addUInt (MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1948
+ AlignInBytes);
1949
+ }
1950
+
1951
+ if (DD->getDwarfVersion () <= 2 ) {
1952
+ DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc;
1953
+ addUInt (*MemLocationDie, dwarf::DW_FORM_data1,
1954
+ dwarf::DW_OP_plus_uconst);
1955
+ addUInt (*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
1956
+ addBlock (MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
1957
+ } else if (!IsBitfield || DD->useDWARF2Bitfields ()) {
1958
+ // In DWARF v3, DW_FORM_data4/8 in DW_AT_data_member_location are
1959
+ // interpreted as location-list pointers. Interpreting constants as
1960
+ // pointers is not expected, so we use DW_FORM_udata to encode the
1961
+ // constants here.
1962
+ if (DD->getDwarfVersion () == 3 )
1963
+ addUInt (MemberDie, dwarf::DW_AT_data_member_location,
1964
+ dwarf::DW_FORM_udata, OffsetInBytes);
1965
+ else
1966
+ addUInt (MemberDie, dwarf::DW_AT_data_member_location, std::nullopt,
1967
+ OffsetInBytes);
1968
+ }
1911
1969
}
1912
1970
}
1913
1971
0 commit comments