@@ -1059,7 +1059,6 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
10591059 // Add name if not anonymous or intermediate type.
10601060 StringRef Name = CTy->getName ();
10611061
1062- uint64_t Size = CTy->getSizeInBits () >> 3 ;
10631062 uint16_t Tag = Buffer.getTag ();
10641063
10651064 switch (Tag) {
@@ -1222,15 +1221,24 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
12221221 if (Tag == dwarf::DW_TAG_enumeration_type ||
12231222 Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type ||
12241223 Tag == dwarf::DW_TAG_union_type) {
1225- // Add size if non-zero (derived types might be zero-sized.)
1226- // Ignore the size if it's a non-enum forward decl.
1227- // TODO: Do we care about size for enum forward declarations?
1228- if (Size &&
1229- (!CTy->isForwardDecl () || Tag == dwarf::DW_TAG_enumeration_type))
1230- addUInt (Buffer, dwarf::DW_AT_byte_size, std::nullopt , Size);
1231- else if (!CTy->isForwardDecl ())
1232- // Add zero size if it is not a forward declaration.
1233- addUInt (Buffer, dwarf::DW_AT_byte_size, std::nullopt , 0 );
1224+ if (auto *Var = dyn_cast_or_null<DIVariable>(CTy->getRawSizeInBits ())) {
1225+ if (auto *VarDIE = getDIE (Var))
1226+ addDIEEntry (Buffer, dwarf::DW_AT_bit_size, *VarDIE);
1227+ } else if (auto *Exp =
1228+ dyn_cast_or_null<DIExpression>(CTy->getRawSizeInBits ())) {
1229+ addBlock (Buffer, dwarf::DW_AT_bit_size, Exp);
1230+ } else {
1231+ uint64_t Size = CTy->getSizeInBits () >> 3 ;
1232+ // Add size if non-zero (derived types might be zero-sized.)
1233+ // Ignore the size if it's a non-enum forward decl.
1234+ // TODO: Do we care about size for enum forward declarations?
1235+ if (Size &&
1236+ (!CTy->isForwardDecl () || Tag == dwarf::DW_TAG_enumeration_type))
1237+ addUInt (Buffer, dwarf::DW_AT_byte_size, std::nullopt , Size);
1238+ else if (!CTy->isForwardDecl ())
1239+ // Add zero size if it is not a forward declaration.
1240+ addUInt (Buffer, dwarf::DW_AT_byte_size, std::nullopt , 0 );
1241+ }
12341242
12351243 // If we're a forward decl, say so.
12361244 if (CTy->isForwardDecl ())
@@ -1884,74 +1892,110 @@ DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
18841892
18851893 addBlock (MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie);
18861894 } else {
1887- uint64_t Size = DT->getSizeInBits ();
1888- uint64_t FieldSize = DD->getBaseTypeSize (DT);
1889- uint32_t AlignInBytes = DT->getAlignInBytes ();
1890- uint64_t OffsetInBytes;
1895+ uint64_t Size = 0 ;
1896+ uint64_t FieldSize = 0 ;
18911897
18921898 bool IsBitfield = DT->isBitField ();
1893- if (IsBitfield) {
1894- // Handle bitfield, assume bytes are 8 bits.
1895- if (DD->useDWARF2Bitfields ())
1896- addUInt (MemberDie, dwarf::DW_AT_byte_size, std::nullopt , FieldSize / 8 );
1897- addUInt (MemberDie, dwarf::DW_AT_bit_size, std::nullopt , Size);
1898-
1899- assert (DT->getOffsetInBits () <=
1900- (uint64_t )std::numeric_limits<int64_t >::max ());
1901- int64_t Offset = DT->getOffsetInBits ();
1902- // We can't use DT->getAlignInBits() here: AlignInBits for member type
1903- // is non-zero if and only if alignment was forced (e.g. _Alignas()),
1904- // which can't be done with bitfields. Thus we use FieldSize here.
1905- uint32_t AlignInBits = FieldSize;
1906- uint32_t AlignMask = ~(AlignInBits - 1 );
1907- // The bits from the start of the storage unit to the start of the field.
1908- uint64_t StartBitOffset = Offset - (Offset & AlignMask);
1909- // The byte offset of the field's aligned storage unit inside the struct.
1910- OffsetInBytes = (Offset - StartBitOffset) / 8 ;
1911-
1912- if (DD->useDWARF2Bitfields ()) {
1913- uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1914- uint64_t FieldOffset = (HiMark - FieldSize);
1915- Offset -= FieldOffset;
1916-
1917- // Maybe we need to work from the other end.
1918- if (Asm->getDataLayout ().isLittleEndian ())
1919- Offset = FieldSize - (Offset + Size);
1920-
1921- if (Offset < 0 )
1922- addSInt (MemberDie, dwarf::DW_AT_bit_offset, dwarf::DW_FORM_sdata,
1899+
1900+ // Handle the size.
1901+ if (DT->getRawSizeInBits () == nullptr ) {
1902+ // No size, just ignore.
1903+ } else if (auto *Var = dyn_cast<DIVariable>(DT->getRawSizeInBits ())) {
1904+ if (auto *VarDIE = getDIE (Var))
1905+ addDIEEntry (MemberDie, dwarf::DW_AT_bit_size, *VarDIE);
1906+ } else if (auto *Exp = dyn_cast<DIExpression>(DT->getRawSizeInBits ())) {
1907+ addBlock (MemberDie, dwarf::DW_AT_bit_size, Exp);
1908+ } else {
1909+ Size = DT->getSizeInBits ();
1910+ FieldSize = DD->getBaseTypeSize (DT);
1911+ if (IsBitfield) {
1912+ // Handle bitfield, assume bytes are 8 bits.
1913+ if (DD->useDWARF2Bitfields ())
1914+ addUInt (MemberDie, dwarf::DW_AT_byte_size, std::nullopt ,
1915+ FieldSize / 8 );
1916+ addUInt (MemberDie, dwarf::DW_AT_bit_size, std::nullopt , Size);
1917+ }
1918+ }
1919+
1920+ // Handle the location. DW_AT_data_bit_offset won't allow an
1921+ // expression until DWARF 6, but it can be used as an extension.
1922+ // See https://dwarfstd.org/issues/250501.1.html
1923+ if (auto *Var = dyn_cast_or_null<DIVariable>(DT->getRawOffsetInBits ())) {
1924+ if (!Asm->TM .Options .DebugStrictDwarf || DD->getDwarfVersion () >= 6 ) {
1925+ if (auto *VarDIE = getDIE (Var))
1926+ addDIEEntry (MemberDie, dwarf::DW_AT_data_bit_offset, *VarDIE);
1927+ }
1928+ } else if (auto *Expr =
1929+ dyn_cast_or_null<DIExpression>(DT->getRawOffsetInBits ())) {
1930+ if (!Asm->TM .Options .DebugStrictDwarf || DD->getDwarfVersion () >= 6 ) {
1931+ addBlock (MemberDie, dwarf::DW_AT_data_bit_offset, Expr);
1932+ }
1933+ } else {
1934+ uint32_t AlignInBytes = DT->getAlignInBytes ();
1935+ uint64_t OffsetInBytes;
1936+
1937+ if (IsBitfield) {
1938+ assert (DT->getOffsetInBits () <=
1939+ (uint64_t )std::numeric_limits<int64_t >::max ());
1940+ int64_t Offset = DT->getOffsetInBits ();
1941+ // We can't use DT->getAlignInBits() here: AlignInBits for member type
1942+ // is non-zero if and only if alignment was forced (e.g. _Alignas()),
1943+ // which can't be done with bitfields. Thus we use FieldSize here.
1944+ uint32_t AlignInBits = FieldSize;
1945+ uint32_t AlignMask = ~(AlignInBits - 1 );
1946+ // The bits from the start of the storage unit to the start of the
1947+ // field.
1948+ uint64_t StartBitOffset = Offset - (Offset & AlignMask);
1949+ // The byte offset of the field's aligned storage unit inside the
1950+ // struct.
1951+ OffsetInBytes = (Offset - StartBitOffset) / 8 ;
1952+
1953+ if (DD->useDWARF2Bitfields ()) {
1954+ uint64_t HiMark = (Offset + FieldSize) & AlignMask;
1955+ uint64_t FieldOffset = (HiMark - FieldSize);
1956+ Offset -= FieldOffset;
1957+
1958+ // Maybe we need to work from the other end.
1959+ if (Asm->getDataLayout ().isLittleEndian ())
1960+ Offset = FieldSize - (Offset + Size);
1961+
1962+ if (Offset < 0 )
1963+ addSInt (MemberDie, dwarf::DW_AT_bit_offset, dwarf::DW_FORM_sdata,
1964+ Offset);
1965+ else
1966+ addUInt (MemberDie, dwarf::DW_AT_bit_offset, std::nullopt ,
1967+ (uint64_t )Offset);
1968+ OffsetInBytes = FieldOffset >> 3 ;
1969+ } else {
1970+ addUInt (MemberDie, dwarf::DW_AT_data_bit_offset, std::nullopt ,
19231971 Offset);
1924- else
1925- addUInt (MemberDie, dwarf::DW_AT_bit_offset, std::nullopt ,
1926- (uint64_t )Offset);
1927- OffsetInBytes = FieldOffset >> 3 ;
1972+ }
19281973 } else {
1929- addUInt (MemberDie, dwarf::DW_AT_data_bit_offset, std::nullopt , Offset);
1974+ // This is not a bitfield.
1975+ OffsetInBytes = DT->getOffsetInBits () / 8 ;
1976+ if (AlignInBytes)
1977+ addUInt (MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1978+ AlignInBytes);
19301979 }
1931- } else {
1932- // This is not a bitfield.
1933- OffsetInBytes = DT->getOffsetInBits () / 8 ;
1934- if (AlignInBytes)
1935- addUInt (MemberDie, dwarf::DW_AT_alignment, dwarf::DW_FORM_udata,
1936- AlignInBytes);
1937- }
19381980
1939- if (DD->getDwarfVersion () <= 2 ) {
1940- DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc;
1941- addUInt (*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
1942- addUInt (*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
1943- addBlock (MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
1944- } else if (!IsBitfield || DD->useDWARF2Bitfields ()) {
1945- // In DWARF v3, DW_FORM_data4/8 in DW_AT_data_member_location are
1946- // interpreted as location-list pointers. Interpreting constants as
1947- // pointers is not expected, so we use DW_FORM_udata to encode the
1948- // constants here.
1949- if (DD->getDwarfVersion () == 3 )
1950- addUInt (MemberDie, dwarf::DW_AT_data_member_location,
1951- dwarf::DW_FORM_udata, OffsetInBytes);
1952- else
1953- addUInt (MemberDie, dwarf::DW_AT_data_member_location, std::nullopt ,
1954- OffsetInBytes);
1981+ if (DD->getDwarfVersion () <= 2 ) {
1982+ DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc;
1983+ addUInt (*MemLocationDie, dwarf::DW_FORM_data1,
1984+ dwarf::DW_OP_plus_uconst);
1985+ addUInt (*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
1986+ addBlock (MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
1987+ } else if (!IsBitfield || DD->useDWARF2Bitfields ()) {
1988+ // In DWARF v3, DW_FORM_data4/8 in DW_AT_data_member_location are
1989+ // interpreted as location-list pointers. Interpreting constants as
1990+ // pointers is not expected, so we use DW_FORM_udata to encode the
1991+ // constants here.
1992+ if (DD->getDwarfVersion () == 3 )
1993+ addUInt (MemberDie, dwarf::DW_AT_data_member_location,
1994+ dwarf::DW_FORM_udata, OffsetInBytes);
1995+ else
1996+ addUInt (MemberDie, dwarf::DW_AT_data_member_location, std::nullopt ,
1997+ OffsetInBytes);
1998+ }
19551999 }
19562000 }
19572001
0 commit comments