Skip to content

Commit 3b90597

Browse files
authored
Non constant size and offset in DWARF (#141106)
In Ada, a record type can have a non-constant size, and a field can appear at a non-constant bit offset in a record. To support this, this patch changes DIType to record the size and offset using metadata, rather than plain integers. In addition to a constant offset, both DIVariable and DIExpression are now supported here. One thing of note in this patch is the choice of how exactly to represent a non-constant bit offset, with the difficulty being that DWARF 5 does not support this. DWARF 3 did have a way to support a non-constant byte offset, combined with a constant bit offset within the byte, but this was deprecated in DWARF 4 and removed from DWARF 5. This patch takes a simple approach: a DWARF extension allowing the use of an expression with DW_AT_data_bit_offset. There is a corresponding DWARF issue, see https://dwarfstd.org/issues/250501.1.html. The main reason for this approach is that it keeps API simplicity: just a single value is needed, rather than having separate data describing the byte offset and the bit within the byte.
1 parent 487581b commit 3b90597

File tree

14 files changed

+975
-364
lines changed

14 files changed

+975
-364
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -841,8 +841,8 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
841841
auto *ISATy = DBuilder.createPointerType(ClassTy, Size);
842842

843843
ObjTy = DBuilder.createStructType(TheCU, "objc_object", TheCU->getFile(), 0,
844-
0, 0, llvm::DINode::FlagZero, nullptr,
845-
llvm::DINodeArray());
844+
(uint64_t)0, 0, llvm::DINode::FlagZero,
845+
nullptr, llvm::DINodeArray());
846846

847847
DBuilder.replaceArrays(
848848
ObjTy, DBuilder.getOrCreateArray(&*DBuilder.createMemberType(

llvm/include/llvm/IR/DIBuilder.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,22 @@ namespace llvm {
367367
uint32_t VBPtrOffset,
368368
DINode::DIFlags Flags);
369369

370+
/// Create debugging information entry for a member.
371+
/// \param Scope Member scope.
372+
/// \param Name Member name.
373+
/// \param File File where this member is defined.
374+
/// \param LineNo Line number.
375+
/// \param SizeInBits Member size.
376+
/// \param AlignInBits Member alignment.
377+
/// \param OffsetInBits Member offset.
378+
/// \param Flags Flags to encode member attribute, e.g. private
379+
/// \param Ty Parent type.
380+
/// \param Annotations Member annotations.
381+
LLVM_ABI DIDerivedType *createMemberType(
382+
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo,
383+
Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits,
384+
DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations = nullptr);
385+
370386
/// Create debugging information entry for a member.
371387
/// \param Scope Member scope.
372388
/// \param Name Member name.
@@ -419,6 +435,23 @@ namespace llvm {
419435
Constant *Discriminant,
420436
DIType *Ty);
421437

438+
/// Create debugging information entry for a bit field member.
439+
/// \param Scope Member scope.
440+
/// \param Name Member name.
441+
/// \param File File where this member is defined.
442+
/// \param LineNo Line number.
443+
/// \param SizeInBits Member size.
444+
/// \param OffsetInBits Member offset.
445+
/// \param StorageOffsetInBits Member storage offset.
446+
/// \param Flags Flags to encode member attribute.
447+
/// \param Ty Parent type.
448+
/// \param Annotations Member annotations.
449+
LLVM_ABI DIDerivedType *createBitFieldMemberType(
450+
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNo,
451+
Metadata *SizeInBits, Metadata *OffsetInBits,
452+
uint64_t StorageOffsetInBits, DINode::DIFlags Flags, DIType *Ty,
453+
DINodeArray Annotations = nullptr);
454+
422455
/// Create debugging information entry for a bit field member.
423456
/// \param Scope Member scope.
424457
/// \param Name Member name.
@@ -510,6 +543,29 @@ namespace llvm {
510543
unsigned RunTimeLang = 0, DIType *VTableHolder = nullptr,
511544
MDNode *TemplateParms = nullptr, StringRef UniqueIdentifier = "");
512545

546+
/// Create debugging information entry for a struct.
547+
/// \param Scope Scope in which this struct is defined.
548+
/// \param Name Struct name.
549+
/// \param File File where this member is defined.
550+
/// \param LineNumber Line number.
551+
/// \param SizeInBits Member size.
552+
/// \param AlignInBits Member alignment.
553+
/// \param Flags Flags to encode member attribute, e.g. private
554+
/// \param Elements Struct elements.
555+
/// \param RunTimeLang Optional parameter, Objective-C runtime version.
556+
/// \param UniqueIdentifier A unique identifier for the struct.
557+
/// \param Specification The type that this type completes. This is used by
558+
/// Swift to represent generic types.
559+
/// \param NumExtraInhabitants The number of extra inhabitants of the type.
560+
/// An extra inhabitant is a bit pattern that does not represent a valid
561+
/// value for instances of a given type. This is used by the Swift language.
562+
LLVM_ABI DICompositeType *createStructType(
563+
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
564+
Metadata *SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,
565+
DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang = 0,
566+
DIType *VTableHolder = nullptr, StringRef UniqueIdentifier = "",
567+
DIType *Specification = nullptr, uint32_t NumExtraInhabitants = 0);
568+
513569
/// Create debugging information entry for a struct.
514570
/// \param Scope Scope in which this struct is defined.
515571
/// \param Name Struct name.

0 commit comments

Comments
 (0)