summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
AgeCommit message (Collapse)Author
2025-11-18Introduce DwarfUnit::addBlock helper method (#168446)Tom Tromey
This patch is just a small cleanup that unifies the various spots that add a DWARF expression to the output.
2025-11-11Remove unused <utility> inclusionserge-sans-paille
Per https://llvm.org/docs/CodingStandards.html#include-as-little-as-possible this improves compilation time, while not being too intrusive on the codebase.
2025-10-31[llvm][DebugInfo][ObjC] Make sure we link backing ivars to their ↵Michael Buch
DW_TAG_APPLE_property (#165409) Depends on: * https://github.com/llvm/llvm-project/pull/165373 When an Objective-C property has a backing ivar, we would previously not add a `DW_AT_APPLE_property` to the ivar's `DW_TAG_member`. This is what was intended based on the [Objective-C DebugInfo docs](https://github.com/llvm/llvm-project/blob/main/llvm/docs/SourceLevelDebugging.rst#proposal) but is not what LLVM currently generates. LLDB currently doesn't ever try linking the `ObjCPropertyDecl`s to their `ObjCIvarDecl`s, but if we wanted to, this debug-info patch is a pre-requisite.
2025-10-29[DebugInfo] Add dataSize to DIBasicType to add DW_AT_bit_size to _BitInt ↵Orlando Cazalet-Hyams
types (#164372) DW_TAG_base_type DIEs are permitted to have both byte_size and bit_size attributes "If the value of an object of the given type does not fully occupy the storage described by a byte size attribute" * Add DataSizeInBits to DIBasicType (`DIBasicType(... dataSize: n ...)` in IR). * Change Clang to add DataSizeInBits to _BitInt type metadata. * Change LLVM to add DW_AT_bit_size to base_type DIEs that have non-zero DataSizeInBits. TODO: Do we need to emit DW_AT_data_bit_offset for big endian targets? See discussion on the PR. Fixes [#61952](https://github.com/llvm/llvm-project/issues/61952) --------- Co-authored-by: David Stenberg <david.stenberg@ericsson.com>
2025-10-11[llvm][DebugInfo] Support versioned source language names in DwarfUnit (#162625)Michael Buch
Depends on: * https://github.com/llvm/llvm-project/pull/162621 Now we can start emitting `DW_AT_language_name`, make sure `DwarfUnit::getSourceLanguage` is equipped to handle this. Otherwise the new test-case would assert.
2025-10-08[llvm][DebugInfo][NFC] Abstract DICompileUnit::SourceLanguage to allow ↵Michael Buch
alternate DWARF SourceLanguage encoding (#162255) This patch sets up `DICompileUnit` to support the DWARFv6 `DW_AT_language_name` and `DW_AT_language_version` attributes (which are set to replace `DW_AT_language`). This patch changes the `DICompileUnit::SourceLanguage` field type to a `DISourceLanguageName` that encapsulates the notion of "versioned vs. unversioned name". A "versioned" name is one that has an associated version stored separately in `DISourceLanguageName::Version`. This patch just changes all the clients of the `getSourceLanguage` API to the expect a `DISourceLanguageName`. Currently they all just `assert` (via `DISourceLanguageName::getUnversionedName`) that we're dealing with "unversioned names" (i.e., the pre-DWARFv6 language codes). In follow-up patches (e.g., draft is at https://github.com/llvm/llvm-project/pull/162261), when we start emitting versioned language codes, the `getUnversionedName` calls can then be adjusted to `getName`. **Implementation considerations** * We could have added a new member to `DICompileUnit` alongside the existing `SourceLanguage` field. I don't think this would have made the transition any simpler (clients would still need to be aware of "versioned" vs. "unversioned" language names). I felt that encapsulating this inside a `DISourceLanguageName` was easier to reason about for maintainers. * Currently DISourceLanguageName is a `12` byte structure. We could probably pack all the info inside a `uint64_t` (16-bits for the name, 32-bits for the version, 1-bit for answering the `hasVersionedName`). Just to keep the prototype simple I used a `std::optional`. But since the guts of the structure are hidden, we can always change the layout to a more compact representation instead. **How to review** * The new `DISourceLanguageName` structure is defined in `DebugInfoMetadata.h`. All the other changes fall out from changing the `DICompileUnit::SourceLanguage` from `unsigned` to `DISourceLanguageName`.
2025-10-02Omit member size from DWARF when desired (#161423)Tom Tromey
2025-09-29Reland "[DebugInfo][DwarfDebug] Separate creation and population of abstract ↵Vladislav Dzhidzhoev
subprogram DIEs" (#160786) This is an attempt to reland https://github.com/llvm/llvm-project/pull/159104 with the fix for https://github.com/llvm/llvm-project/issues/160197. The original patch had the following problem: when an abstract subprogram DIE is constructed from within `DwarfDebug::endFunctionImpl()`, `DwarfDebug::constructAbstractSubprogramScopeDIE()` acknowledges `unit:` field of DISubprogram. But an abstract subprogram DIE constructed from `DwarfDebug::beginModule()` was put in the same compile unit to which global variable referencing the subprogram belonged, regardless of subprogram's `unit:`. This is fixed by adding `DwarfDebug::getOrCreateAbstractSubprogramCU()` used by both`DwarfDebug:: constructAbstractSubprogramScopeDIE()` and `DwarfCompileUnit::getOrCreateSubprogramDIE()` when abstract subprogram is queried during the creation of DIEs for globals in `DwarfDebug::beginModule()`. The fix and the already-reviewed code from https://github.com/llvm/llvm-project/pull/159104 are two separate commits in this PR. ===== The original commit message follows: With this change, construction of abstract subprogram DIEs is split in two stages/functions: creation of DIE (in DwarfCompileUnit::getOrCreateAbstractSubprogramDIE) and its population with children (in DwarfCompileUnit::constructAbstractSubprogramScopeDIE). With that, abstract subprograms can be created/referenced from DwarfDebug::beginModule, which should solve the issue with static local variables DIE creation of inlined functons with optimized-out definitions. It fixes https://github.com/llvm/llvm-project/issues/29985. LexicalScopes class now stores mapping from DISubprograms to their corresponding llvm::Function's. It is supposed to be built before processing of each function (so, now LexicalScopes class has a method for "module initialization" alongside the method for "function initialization"). It is used by DwarfCompileUnit to determine whether a DISubprogram needs an abstract DIE before DwarfDebug::beginFunction is invoked. DwarfCompileUnit::getOrCreateSubprogramDIE method is added, which can create an abstract or a concrete DIE for a subprogram. It accepts llvm::Function* argument to determine whether a concrete DIE must be created. This is a temporary fix for https://github.com/llvm/llvm-project/issues/29985. Ideally, it will be fixed by moving global variables and types emission to DwarfDebug::endModule (https://reviews.llvm.org/D144007, https://reviews.llvm.org/D144005). Some code proposed by Ellis Hoag <ellis.sparky.hoag@gmail.com> in https://github.com/llvm/llvm-project/pull/90523 was taken for this commit.
2025-09-23Revert "[DebugInfo][DwarfDebug] Separate creation and population of abstract ↵Vladislav Dzhidzhoev
subprogram DIEs" (#160349) Reverts llvm/llvm-project#159104 due to the issues reported in https://github.com/llvm/llvm-project/issues/160197.
2025-09-17[DebugInfo][DwarfDebug] Separate creation and population of abstract ↵Vladislav Dzhidzhoev
subprogram DIEs (#159104) With this change, construction of abstract subprogram DIEs is split in two stages/functions: creation of DIE (in DwarfCompileUnit::getOrCreateAbstractSubprogramDIE) and its population with children (in DwarfCompileUnit::constructAbstractSubprogramScopeDIE). With that, abstract subprograms can be created/referenced from DwarfDebug::beginModule, which should solve the issue with static local variables DIE creation of inlined functons with optimized-out definitions. It fixes https://github.com/llvm/llvm-project/issues/29985. LexicalScopes class now stores mapping from DISubprograms to their corresponding llvm::Function's. It is supposed to be built before processing of each function (so, now LexicalScopes class has a method for "module initialization" alongside the method for "function initialization"). It is used by DwarfCompileUnit to determine whether a DISubprogram needs an abstract DIE before DwarfDebug::beginFunction is invoked. DwarfCompileUnit::getOrCreateSubprogramDIE method is added, which can create an abstract or a concrete DIE for a subprogram. It accepts llvm::Function* argument to determine whether a concrete DIE must be created. This is a temporary fix for https://github.com/llvm/llvm-project/issues/29985. Ideally, it will be fixed by moving global variables and types emission to DwarfDebug::endModule (https://reviews.llvm.org/D144007, https://reviews.llvm.org/D144005). Some code proposed by Ellis Hoag <ellis.sparky.hoag@gmail.com> in https://github.com/llvm/llvm-project/pull/90523 was taken for this commit.
2025-09-01[llvm][DebugInfo] Support DW_AT_linkage_names that are different between ↵Michael Buch
declaration and definition (#154137) This patch is motivated by https://github.com/llvm/llvm-project/pull/149827, where we plan on using mangled names on structor declarations to find the exact structor definition that LLDB's expression evaluator should call. So far LLVM expects the declaration and definition linkage names to be identical (or the declaration to just not have a linkage name). But we plan on attaching the GCC-style "unified" mangled name to declarations, which will be different to linkage name on the definition. This patch relaxes this restriction.
2025-08-29[DwarfDebug] Avoid generating extra DW_TAG_subprogram entries (#154636)Vladislav Dzhidzhoev
The test llvm/test/DebugInfo/X86/pr12831.ll was added in 4d358b55fa to fix the issue with emission of empty DW_TAG_subprogram tags (https://bugs.llvm.org/show_bug.cgi?id=12831). However, the test output is not checked properly, and it contains: ``` 0x00000206: DW_TAG_subprogram 0x00000207: DW_TAG_reference_type DW_AT_type (0x00000169 "class ") ``` The reason is that the DIE for the definition DISubprogram "writeExpr" is created during the call to `getOrCreateSubprogramDIE(declaration of writeExpr)`. Therefore, when `getOrCreateSubprogramDIE(definition of writeExpr)` is first called, we get a recursive chain of calls: ``` getOrCreateSubprogramDIE(definition of writeExpr) getOrCreateSubprogramDIE(declaration of writeExpr) ... getOrCreateSubprogramDIE(definition of writeExpr) ``` The outer call doesn't expect that the DIE for the definition of writeExpr will be created during the creation of declaration DIE. So, another DIE is created for the same subprogram. In this PR, a check is added to fix that.
2025-07-04[debuginfo][coro] Emit debug info labels for coroutine resume points (#141937)Adrian Vogelsgesang
RFC on discourse: https://discourse.llvm.org/t/rfc-debug-info-for-coroutine-suspension-locations-take-2/86606 With this commit, we add `DILabel` debug infos to the resume points of a coroutine. Those labels can be used by debugging scripts to figure out the exact line and column at which a coroutine was suspended by looking up current `__coro_index` value inside the coroutines frame, and then searching for the corresponding label inside the coroutine's resume function. The DWARF information generated for such a label looks like: ``` 0x00000f71: DW_TAG_label DW_AT_name ("__coro_resume_1") DW_AT_decl_file ("generator-example.cpp") DW_AT_decl_line (5) DW_AT_decl_column (3) DW_AT_artificial (true) DW_AT_LLVM_coro_suspend_idx (0x01) DW_AT_low_pc (0x00000000000019be) ``` The labels can be mapped to their corresponding `__coro_idx` values either via their naming convention `__coro_resume_<N>` or using the new `DW_AT_LLVM_coro_suspend_idx` attribute. In gdb, those line numebrs can be looked up using `info line -function my_coroutine -label __coro_resume_1`. LLDB unfortunately does not understand DW_TAG_label debug information, yet. Given this is an artificial compiler-generated label, I did apply the DW_AT_artificial tag to it. The DWARFv5 standard only allows that tag on type and variable definitions, but this is a natural extension and was also blessed in the RFC on discourse. Also, this commit adds `DW_AT_decl_column` to labels, not only for coroutines but also for normal C and C++ labels. While not strictly necessary, I am doing so now because it would be harder to do so later without breaking the binary LLVM-IR format Drive-by fixes: While reading the existing test cases to understand how to write my own test case, I did a couple of small typo fixes and comment improvements
2025-06-25Non constant size and offset in DWARF (#141106)Tom Tromey
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.
2025-06-16[llvm][DebugInfo] Encode DW_AT_object_pointer on method declarations with ↵Michael Buch
DW_FORM_implicit_const (#124790) We started attaching `DW_AT_object_pointer`s on method declarations in https://github.com/llvm/llvm-project/pull/122742. However, that caused the `.debug_info` section size to increase significantly (by around ~10% on some projects). This was mainly due to the large number of new `DW_FORM_ref4` values. This patch tries to address that regression by changing the `DW_FORM_ref4` to a `DW_FORM_implicit_const` for declarations. The value of `DW_FORM_implicit_const` will be the *index* of the object parameter in the list of formal parameters of the subprogram (i.e., if the first `DW_TAG_formal_parameter` is the object pointer, the `DW_FORM_implicit_const` would be `0`). The DWARFv5 spec only mentions the use of the `reference` attribute class to for `DW_AT_object_pointer`. So using a `DW_FORM_impilicit_const` would be an extension to (and not something mandated/specified by) the standard. Though it'd make sense to extend the wording in the spec to allow for this optimization. That way we don't pay for the 4 byte references on every attribute occurrence. In a local build of clang this barely affected the `.debug_info` section size (but did increase `.debug_abbrev` by up to 10%, which doesn't impact the total debug-info size much however). We guarded this on LLDB tuning (since using `DW_FORM_implicit_const` for this purpose may surprise consumers) and DWARFv5 (since that's where `DW_FORM_implicit_const` was first standardized).
2025-06-05[DebugInfo] Use correct unit when creating variable across CU boundary (#133282)Jeremy Morse
When creating a static member DIE, we place it in a potentially pre-existing context DIE, and that DIE might be located in a different CU if we're in an LTO context. When we then add the source-file-ID to the static member DIE, use the correct Unit to do so -- the one that owns the context DIE. Otherwise we might assign a file-ID from one CU to another, and there isn't a guarantee that they'll be the same file, or even exist. Fixes #109227 (I'd normally remove my home directory from these tests, but in this circumstances the same-file-but-with-a-different-name nature of the DIFile is part of the test).
2025-05-12Allow multi-member variants in DWARF (#139300)Tom Tromey
Currently, each variant in the variant part of a structure type can only contain a single member. This was sufficient for Rust, where each variant is represented as its own type. However, this isn't really enough for Ada, where a variant can have multiple members. This patch adds support for this scenario. This is done by allowing the use of DW_TAG_variant by DICompositeType, and then changing the DWARF generator to recognize when a DIDerivedType representing a variant holds one of these. In this case, the fields from the DW_TAG_variant are inlined into the variant, like so: ``` <4><7d>: Abbrev Number: 9 (DW_TAG_variant) <7e> DW_AT_discr_value : 74 <5><7f>: Abbrev Number: 7 (DW_TAG_member) <80> DW_AT_name : (indirect string, offset: 0x43): field0 <84> DW_AT_type : <0xa7> <88> DW_AT_alignment : 8 <89> DW_AT_data_member_location: 0 <5><8a>: Abbrev Number: 7 (DW_TAG_member) <8b> DW_AT_name : (indirect string, offset: 0x4a): field1 <8f> DW_AT_type : <0xa7> <93> DW_AT_alignment : 8 <94> DW_AT_data_member_location: 8 ``` Note that the intermediate DIDerivedType is still needed in this situation, because that is where the discriminants are stored.
2025-05-08Two DWARF variant part improvements (#138953)Tom Tromey
This patch adds a couple of improvements to the LLVM emission of DWARF variant parts. One of these is desirable for Ada, and the other is required. Currently, when emitting a discriminant, LLVM follows the precise letter of the DWARF standard, which says: If the variant part has a discriminant, the discriminant is represented by a separate debugging information entry which is a child of the variant part entry. However, for Ada this does not really make sense. In Ada, the discriminant field exists outside of any variant part, and it makes more sense to emit it separately rather than redundantly emit the field once for each variant part. This extension was arrived at when this was implemented in GCC, and was accepted for DWARF 6, see: https://dwarfstd.org/issues/180123.1.html Here the patch simply lifts this restriction: if the discriminant field was already emitted, it isn't re-emitted. This approach allows the Ada compiler to do what it needs without affecting the Rust output. Second, this patch extends the discriminant to allow multiple values. This is needed by Ada. Here, I chose to use a ConstantDataArray of pairs of integers, with each pair representing a range, as Ada also allows ranges here. This seemed like a reasonably convenient representation.
2025-04-15[AsmPrinter] Migrate away from PointerUnion::dyn_cast (NFC) (#135740)Kazu Hirata
Note that PointerUnion::dyn_cast has been soft deprecated in PointerUnion.h: // FIXME: Replace the uses of is(), get() and dyn_cast() with // isa<T>, cast<T> and the llvm::dyn_cast<T> We use dyn_cast_if_present here because Bound can be null.
2025-03-31Add support for fixed-point types (#129596)Tom Tromey
This adds DWARF generation for fixed-point types. This feature is needed by Ada. Note that a pre-existing GNU extension is used in one case. This has been emitted by GCC for years, and is needed because standard DWARF is otherwise incapable of representing these types.
2025-03-25Add bit stride to DICompositeType (#131680)Tom Tromey
In Ada, an array can be packed and the elements can take less space than their natural object size. For example, for this type: type Packed_Array is array (4 .. 8) of Boolean; pragma pack (Packed_Array); ... each element of the array occupies a single bit, even though the "natural" size for a Boolean in memory is a byte. In DWARF, this is represented by putting a DW_AT_bit_stride onto the array type itself. This patch adds a bit stride to DICompositeType so that gnat-llvm can emit DWARF for these sorts of arrays.
2025-03-07Two fixes for DISubrangeType (#130345)Tom Tromey
My previous patch to add DISubrangeType (#126772) had a couple of minor errors. This patch corrects them. 1. When using a DISubrangeType as an array index type, the wrong tag was written into the DIE. 2. I'd intended for subranges to use bit strides, not byte strides -- but neglected to actually implement this. Ada needs bit strides. This patch adds a new test that checks both these things. Finally, this patch adds some documentation for DISubrangeType.
2025-02-24Add DISubrangeType (#126772)Tom Tromey
An Ada program can have types that are subranges of other types. This patch adds a new DIType node, DISubrangeType, to represent this concept. I considered extending the existing DISubrange to do this, but as DISubrange does not derive from DIType, that approach seemed more disruptive. A DISubrangeType can be used both as an ordinary type, but also as the type of an array index. This is also important for Ada. Ada subrange types can also be stored using a bias. Representing this in the DWARF required the use of an extension. GCC has been emitting this extension for years, so I've reused it here.
2025-02-13[llvm][DebugInfo] Emit DW_AT_const_value for float non-type template ↵Michael Buch
parameters (#127045) In C++20, non-type template parameters can be float/double. Clang didn't emit those constants in DWARF. This patch emits floating point constants the same way we do other integral template value parameters.
2025-02-06[llvm][DebugInfo] Add new DW_AT_APPLE_enum_kind to encode enum_extensibility ↵Michael Buch
(#124752) When creating `EnumDecl`s from DWARF for Objective-C `NS_ENUM`s, the Swift compiler tries to figure out if it should perform "swiftification" of that enum (which involves renaming the enumerator cases, etc.). The heuristics by which it determines whether we want to swiftify an enum is by checking the `enum_extensibility` attribute (because that's what `NS_ENUM` pretty much are). Currently LLDB fails to attach the `EnumExtensibilityAttr` to `EnumDecl`s it creates (because there's not enough info in DWARF to derive it), which means we have to fall back to re-building Swift modules on-the-fly, slowing down expression evaluation substantially. This happens around https://github.com/swiftlang/swift/blob/4b3931c8ce437b3f13f245e6423f95c94a5876ac/lib/ClangImporter/ImportEnumInfo.cpp#L37-L59 To speed up Swift exression evaluation, this patch proposes encoding the C/C++/Objective-C `enum_extensibility` attribute in DWARF via a new `DW_AT_APPLE_ENUM_KIND`. This would currently be only used from the LLDB Swift plugin. But may be of interest to other language plugins as well (though I haven't come up with a concrete use-case for it outside of Swift). I'm open to naming suggestions of the various new attributes/attribute constants proposed here. I tried to be as generic as possible if we wanted to extend it to other kinds of enum properties (e.g., flag enums). The new attribute would look as follows: ``` DW_TAG_enumeration_type DW_AT_type (0x0000003a "unsigned int") DW_AT_APPLE_enum_kind (DW_APPLE_ENUM_KIND_Closed) DW_AT_name ("ClosedEnum") DW_AT_byte_size (0x04) DW_AT_decl_file ("enum.c") DW_AT_decl_line (23) DW_TAG_enumeration_type DW_AT_type (0x0000003a "unsigned int") DW_AT_APPLE_enum_kind (DW_APPLE_ENUM_KIND_Open) DW_AT_name ("OpenEnum") DW_AT_byte_size (0x04) DW_AT_decl_file ("enum.c") DW_AT_decl_line (27) ``` Absence of the attribute means the extensibility of the enum is unknown and abides by whatever the language rules of that CU dictate. This does feel like a big hammer for quite a specific use-case, so I'm happy to discuss alternatives. Alternatives considered: * Re-using an existing DWARF attribute to express extensibility. E.g., a `DW_TAG_enumeration_type` could have a `DW_AT_count` or `DW_AT_upper_bound` indicating the number of enumerators, which could imply closed-ness. I felt like a dedicated attribute (which could be generalized further) seemed more applicable. But I'm open to re-using existing attributes. * Encoding the entire attribute string (i.e., `DW_TAG_LLVM_annotation ("enum_extensibility((open))")`) on the `DW_TAG_enumeration_type`. Then in LLDB somehow parse that out into a `EnumExtensibilityAttr`. I haven't found a great API in Clang to parse arbitrary strings into AST nodes (the ones I've found required fully formed C++ constructs). Though if someone knows of a good way to do this, happy to consider that too.
2025-02-04Allow 128-bit discriminants in DWARF variants (#125578)Tom Tromey
If a variant part has a 128-bit discriminator, then DwarfUnit::constructTypeDIE will assert. This patch fixes the problem by allowing any size of integer to be used here. This is largely accomplished by moving part of DwarfUnit::addConstantValue to a new method. Fixes #119655
2025-01-29Revert "[llvm][DebugInfo] Attach object-pointer to DISubprogram declarations ↵David Blaikie
(#122742)" (#124853) This introduces a substantial (5-10%) regression in .debug_info size, so we're discussing alternatives in #122742 and #124790. This reverts commit 7c729418d721147bf1f2b257afd30f84721888ad.
2025-01-17[llvm][DebugInfo] Attach object-pointer to DISubprogram declarations (#122742)Michael Buch
Currently Clang only attaches `DW_AT_object_pointer` to `DW_TAG_subprogram` definitions. LLDB constructs C++ method types from their `DW_TAG_subprogram` declaration, which is also the point at which it needs to determine whether a method is static or not. LLDB's heuristic for this could be very simple if we emitted `DW_AT_object_pointer` on declarations. But since we don't, LLDB has to guess whether an argument is an implicit object parameter based on the DW_AT_name and DW_AT_type. To simplify LLDB's job (and to eventually support C++23's explicit object parameters), this patch adds the `DIFlagObjectPointer` to `DISubprogram` declarations. For reference, GCC attaches the object-pointer DIE to both the definition and declaration: https://godbolt.org/z/3TWjTfWon Fixes https://github.com/llvm/llvm-project/issues/120973
2024-11-15[DebugInfo] Add DW_AT_artificial for compiler generated static member. (#115851)Carlos Alberto Enciso
Consider the case when the compiler generates a static member. Any consumer of the debug info generated for that case, would benefit if that member has the DW_AT_artificial flag.
2024-11-13[DebugInfo] Add a specification attribute to LLVM DebugInfo (#115362)Augusto Noronha
Add a specification attribute to LLVM DebugInfo, which is analogous to DWARF's DW_AT_specification. According to the DWARF spec: "A debugging information entry that represents a declaration that completes another (earlier) non-defining declaration may have a DW_AT_specification attribute whose value is a reference to the debugging information entry representing the non-defining declaration." This patch allows types to be specifications of other types. This is used by Swift to represent generic types. For example, given this Swift program: ``` struct MyStruct<T> { let t: T } let variable = MyStruct<Int>(t: 43) ``` The Swift compiler emits (roughly) an unsubtituted type for MyStruct<T>: ``` DW_TAG_structure_type DW_AT_name ("MyStruct") // "$s1w8MyStructVyxGD" is a Swift mangled name roughly equivalent to // MyStruct<T> DW_AT_linkage_name ("$s1w8MyStructVyxGD") // other attributes here ``` And a specification for MyStruct<Int>: ``` DW_TAG_structure_type DW_AT_specification (<link to "MyStruct">) // "$s1w8MyStructVySiGD" is a Swift mangled name equivalent to // MyStruct<Int> DW_AT_linkage_name ("$s1w8MyStructVySiGD") DW_AT_byte_size (0x08) // other attributes here ```
2024-11-06[DebugInfo] Add num_extra_inhabitants to debug info (#112590)Augusto Noronha
An extra inhabitant is a bit pattern that does not represent a valid value for instances of a given type. The number of extra inhabitants is the number of those bit configurations. This is used by Swift to save space when composing types. For example, because Bool only needs 2 bit patterns to represent all of its values (true and false), an Optional<Bool> only occupies 1 byte in memory by using a bit configuration that is unused by Bool. Which bit patterns are unused are part of the ABI of the language. Since Swift generics are not monomorphized, by using dynamic libraries you can have generic types whose size, alignment, etc, are known only at runtime (which is why this feature is needed). This patch adds num_extra_inhabitants to LLVM-IR debug info and in DWARF as an Apple extension.
2024-10-22[DebugInfo] Emit linkage name into DWARF for types for Swift (#112802)Augusto Noronha
Store Swift mangled names in DW_AT_linkage_name. The Swift compiler emits only the type mangled name in debug information, and LLDB uses those mangled names as keys to look up size, alignment, fields, etc from either reflection metadata or Swift modules. Additionally, emit types linkage names for types into the accelerator table if they exist and they're different from the display name.
2024-07-12[llvm][DebugInfo] Add DW_AT_type to DW_TAG_enumeration_type in non-strict ↵David Spickett
DWARF v2 mode (#98335) During testing of https://github.com/llvm/llvm-project/pull/96202 we found that when clang set to DWARF v2 was used to build the test file, lldb could not tell that the unsigned enum type was in fact unsigned. So it defaulted to signed and printed the wrong value. The reason for this is that DWARFv2 does not include DW_AT_type in DW_TAG_enumeration_type. This was added in DWARF v3: "The enumeration type entry may also have a DW_AT_type attribute which refers to the underlying data type used to implement the enumeration. In C or C++, the underlying type will be the appropriate integral type determined by the compiler from the properties of the enumeration literal values." I noticed that gcc does emit this attribute for DWARF v2 but not when strict DWARF is requested (more details in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=16063#c7). This patch changes to clang to do the same. This will improve the experience of anyone using tools that can understand the attribute but for whatever reason are stuck building binaries containing v2 only. You can see a current clang/gcc comparison here: https://godbolt.org/z/eG9Kc9WGf https://reviews.llvm.org/D42734 added the original code that emitted this for >= v3 only.
2024-06-20Revert "[DebugInfo][BPF] Add 'annotations' field for DIBasicType & DI… ↵eddyz87
(#96172) …SubroutineType (#91422)" This reverts commit 3ca17443ef4af21bdb1f3b4fbcfff672cbc6176c. As reported in [1,2] the commit above causes CI failure for powerpc-aix target. There is also a performance regression reported in [3]. Reverting to comply with the developer policy. [1] https://github.com/llvm/llvm-project/pull/91422#issuecomment-2179425473 [2] https://lab.llvm.org/buildbot/#/builders/64/builds/62 [3] https://github.com/llvm/llvm-project/pull/91422#issuecomment-2175631443
2024-06-18[DebugInfo][BPF] Add 'annotations' field for DIBasicType & DISubroutineType ↵eddyz87
(#91422) Extend `DIBasicType` and `DISubroutineType` with additional field `annotations`, e.g. as below: ``` !5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, annotations: !6) !6 = !{!7} !7 = !{!"btf:type_tag", !"tag1"} ``` The field would be used by BPF backend to generate DWARF attributes corresponding to `btf_type_tag` type attributes, e.g.: ``` 0x00000029: DW_TAG_base_type DW_AT_name ("int") DW_AT_encoding (DW_ATE_signed) DW_AT_byte_size (0x04) 0x0000002d: DW_TAG_LLVM_annotation DW_AT_name ("btf:type_tag") DW_AT_const_value ("tag1") ``` Such DWARF entries would be used to generate BTF definitions by tools like [pahole](https://github.com/acmel/dwarves). Note: similar fields with similar purposes are already present in DIDerivedType and DICompositeType. Currently "btf_type_tag" attributes are represented in debug information as 'annotations' fields in DIDerivedType with DW_TAG_pointer_type tag. The annotation on a pointer corresponds to pointee having the attributes in the final BTF. The discussion in [thread](https://lore.kernel.org/bpf/87r0w9jjoq.fsf@oracle.com/) came to conclusion, that such annotations should apply to the annotated type itself. Hence the necessity to extend `DIBasicType` & `DISubroutineType` types with 'annotations' field to represent cases like below: ``` int __attribute__((btf_type_tag("foo"))) bar; ``` This was previously tracked as differential revision: https://reviews.llvm.org/D143966
2024-05-22DWARF: debug_names: Don't emit entries for skeleton type unitsDavid Blaikie
When a type unit is emitted, the CU referencing the type unit ends up with a little DW_TAG_*_type with the DW_AT_signature and DW_AT_declaration sometimes referred to (by me? maybe other people?) as a skeleton type. We shouldn't produce .debug_names reference to these - only to the actual type definition in the type unit. So this patch does that. But, inversely, the .debug_gnu_pubtypes /does/ need to reference the skeleton type (& gcc does this too, when it produces a skeleton type (gcc doesn't always produce these - if the type is only referenced once via DW_AT_type, gcc uses a direct DW_FORM_ref_sig8 on the DW_AT_type without the intermediate skeleton type)) - so there's a little special case added in to preserve that behavior which is covered by existing tests.
2024-05-22NFC: DebugInfo: use early return to reduce indentationDavid Blaikie
2024-05-13Fix MSVC "signed/unsigned mismatch" warning. NFC.Simon Pilgrim
2024-05-13[DebugInfo] Emit negative DW_AT_bit_offset in explicit signed form (#87994)Victor Campos
Before this patch, the value of DW_AT_bit_offset, used for bitfields before DWARF version 4, was always emitted as an unsigned integer using the form DW_FORM_data<n>. If the value was originally a signed integer, for instance in the case of negative offsets, it was up to debug information consumers to re-cast it to a signed integer. This is problematic since the burden of deciding if the value should be read as signed or unsigned was put onto the debug info consumers: the DWARF specification doesn't define DW_AT_bit_offset's underlying type. If a debugger decided to interpret this attribute in the form data<n> as unsigned, then negative offsets would be completely broken. The DWARF specification version 3 mentions in the Data Representation section, page 127: > If one of the DW_FORM_data<n> forms is used to represent a signed or unsigned integer, it can be hard for a consumer to discover the context necessary to determine which interpretation is intended. Producers are therefore strongly encouraged to use DW_FORM_sdata or DW_FORM_udata for signed and unsigned integers respectively, rather than DW_FORM_data<n>. Therefore, the proposal is to use DW_FORM_sdata, which is explicitly signed. This is an indication to consumers that the offset must be parsed unambiguously as a signed integer. Finally, gcc already uses DW_FORM_sdata for negative offsets, fixing the potential ambiguity altogether. This patch mimics gcc's behaviour by emitting negative values of DW_AT_bit_offset using the DW_FORM_sdata form. This eliminates any potential misinterpretation. One could argue that all values should use DW_FORM_sdata, but for the sake of parity with gcc, it is safe to restrict the change to negative values.
2024-04-18[DWARF] Add support for DW_TAG_template_alias for template aliases (#88943)Orlando Cazalet-Hyams
Part 1 of fix for issue https://github.com/llvm/llvm-project/issues/54624 Split from PR #87623. Clang front end changes to follow. Use DICompositeType to represent the template alias, using its extraData field as a tuple of DITemplateParameter to describe the template parameters. Added template-alias.ll - Check DWARF emission. Modified frame-types.s - Check llvm-symbolizer understands the DIE.
2024-03-19[Dwarf] Support `__ptrauth` qualifier in metadata nodes (#83862)Daniil Kovalev
Reland #82363 after fixing build failure https://lab.llvm.org/buildbot/#/builders/5/builds/41428. Memory sanitizer detects usage of `RawData` union member which is not filled directly. Instead, the code relies on filling `Data` union member, which is a struct consisting of signing schema parameters. According to https://en.cppreference.com/w/cpp/language/union, this is UB: "It is undefined behavior to read from the member of the union that wasn't most recently written". Instead of relying on compiler allowing us to do dirty things, do not use union and only store `RawData`. Particular ptrauth parameters are obtained on demand via bit operations. Original PR description below. Emit `__ptrauth`-qualified types as `DIDerivedType` metadata nodes in IR with tag `DW_TAG_LLVM_ptrauth_type`, baseType referring to the type which has the qualifier applied, and the following parameters representing the signing schema: - `ptrAuthKey` (integer) - `ptrAuthIsAddressDiscriminated` (boolean) - `ptrAuthExtraDiscriminator` (integer) - `ptrAuthIsaPointer` (boolean) - `ptrAuthAuthenticatesNullValues` (boolean) Co-authored-by: Ahmed Bougacha <ahmed@bougacha.org>
2024-03-02Revert "[Dwarf] Support `__ptrauth` qualifier in metadata nodes" (#83672)Daniil Kovalev
Reverts llvm/llvm-project#82363 See a build failure related to an issue discovered by memory sanitizer (use of uninitialized value): https://lab.llvm.org/buildbot/#/builders/37/builds/31965
2024-03-01[Dwarf] Support `__ptrauth` qualifier in metadata nodes (#82363)Daniil Kovalev
Emit `__ptrauth`-qualified types as `DIDerivedType` metadata nodes in IR with tag `DW_TAG_LLVM_ptrauth_type`, baseType referring to the type which has the qualifier applied, and the following parameters representing the signing schema: - `ptrAuthKey` (integer) - `ptrAuthIsAddressDiscriminated` (boolean) - `ptrAuthExtraDiscriminator` (integer) - `ptrAuthIsaPointer` (boolean) - `ptrAuthAuthenticatesNullValues` (boolean) Co-authored-by: Ahmed Bougacha <ahmed@bougacha.org>
2023-11-18[LLVM][DWARF] Add support for monolithic types in .debug_names (#70515)Alexander Yermolovich
Enable Type Units with DWARF5 accelerator tables for monolithic DWARF. Implementation relies on linker to tombstone offset in LocalTU list to -1 when it deduplciates type units using COMDAT.
2023-10-22[llvm] Stop including llvm/ADT/iterator_range.h (NFC)Kazu Hirata
Identified with misc-include-cleaner.
2023-10-05Revert "[LLVM][DWARF] Add support for monolithic types in .debug_names (#68131)"Nico Weber
This reverts commit 9bbd2bf654634cd95dd0be7948ec8402c3c76e1e. Accidental commit: https://github.com/llvm/llvm-project/pull/68131#issuecomment-1749430207
2023-10-05[LLVM][DWARF] Add support for monolithic types in .debug_names (#68131)Alexander Yermolovich
Added support for Type Units in monolithic DWARF in .debug_names.
2023-06-16Reland "[DebugMetadata][DwarfDebug] Fix DWARF emisson of function-local ↵Vladislav Dzhidzhoev
imported entities (3/7)" Got rid of non-determinism in MetadataLoader.cpp. Authored-by: Kristina Bessonova <kbessonova@accesssoftek.com> Differential Revision: https://reviews.llvm.org/D144004
2023-06-15Revert "Reland "[DebugMetadata][DwarfDebug] Fix DWARF emisson of ↵Vladislav Dzhidzhoev
function-local imported entities (3/7)"" This reverts commit fcc3981626821addc6c77b98006d02030b8ceb7f, since Bitcode-upgrading code doesn't seem to be deterministic.
2023-06-15Reland "[DebugMetadata][DwarfDebug] Fix DWARF emisson of function-local ↵Vladislav Dzhidzhoev
imported entities (3/7)" Run split-dwarf-local-impor3.ll only on x86_64-linux.