Commit Graph

1913 Commits

Author SHA1 Message Date
Emil Pedersen c0cc0827de Merge pull request #89071 from Snowy1803/debug-bb
[DebugInfo] Supplement debug values with Debug Basic Blocks
2026-05-18 17:32:35 +01:00
Aidan Hall af9b7bdad3 Merge pull request #88273 from aidan-hall/keypath-debug-locations
[SILGen] Location hints for keypath accessor thunks
2026-05-14 16:35:32 +01:00
Emil Pedersen d149ac2728 [DebugInfo] Rewrite integer literal salvage using debug basic block
Instead of using an op_constu/consts in the DIExpr, the integer literal
salvage now uses a debug basic block using a typed integer_literal.

This also has the effect of supporting integer literals bigger than
64 bits (such as an Int128 being salvaged) correctly.

Assisted-by: Claude
2026-05-13 16:29:18 +01:00
Emil Pedersen 7907fa75b8 [DebugInfo] Immediately salvage debug basic block instructions in IRGen
Instructions emitted as part of the transform block of a debug_value
are now immediately deleted as soon as the debug record is created.

They are salvaged by LLVM's salvageDebugInfo, and as such, their
effects are encoded into the DIExpression of the debug record.

Assisted-by: Claude
2026-05-13 16:03:53 +01:00
Emil Pedersen aac6dec294 [DebugInfo] Add basic IRGen support to debug basic blocks
Assisted-by: Claude
2026-05-13 16:03:53 +01:00
Emil Pedersen e967cb0f62 Merge pull request #88962 from Snowy1803/refactor-irgen-deref
[IRGen] [DebugInfo] Replace IndirectionKind with op_deref
2026-05-12 21:07:46 +01:00
Emil Pedersen bc79a45bb8 Merge pull request #89031 from Snowy1803/remove-index-addr-salvage
[DebugInfo] Remove salvage for IndexAddrInst
2026-05-12 17:24:42 +01:00
Emil Pedersen f5bfa8396d [IRGen] [DebugInfo] Replace IndirectionKind in DebugInfo handling with op_deref
Instead of using a single DirectValue/IndirectValue enum with duplicate values
for coro context, indirect values are now represented with an extra op_deref
throughout.

This makes the code simpler: Coro context is now a boolean throughout, and
the intent behind indirection is clearer. It also cleanly supports multiple
layers of indirection: if two consecutive paths set the indirection kind to
IndirectValue, it would only insert one DW_OP_deref instead of two.

This fixes the move_function_dbginfo.swift test file with the deref behaviour
(rdar://176552243). All changed test cases have been tested manually in LLDB
to make sure it is the correct behaviour.

Assisted-by: Claude
2026-05-12 16:17:44 +01:00
Emil Pedersen 43f43e0f14 [DebugInfo] Remove salvage for IndexAddrInst
The salvage for this instruction was wrong as it didn't multiply the
index by the element stride.
As this salvage is rare, only was correct for byte sized elements, and
will be rewritten in the future, remove it rather than fix it.
2026-05-12 12:19:10 +01:00
Emil Pedersen e25938e8d0 [Tests] [DebugInfo] Update all tests to use op_deref on address types
All SIL tests now use op_deref correctly on debug_values on address
types, such as alloc_stack. All tests are now conforming to the new
model of always using op_deref for addresses.

Assisted-by: Claude
2026-05-12 11:24:47 +01:00
Emil Pedersen 855bc127d5 [DebugInfo] Add implicit op_deref to AllocStackInst
The VarInfo for an alloc_stack will always have an op_deref, so that they can
get copied along when the VarInfo is moved to a debug_value. This op_deref is
not printed by the SILPrinter.

This commit also updates uses of AllocStackInst's getVarInfo to strip this
op_deref at places where it is not needed, and uses of createDebugValueAddr
where the extra op_deref is no longer needed.

The only change at the IR level is for undef values that now have a DW_OP_deref
for move-only values.

This fixes most of the inconsitencies with op_deref at the SIL level. All
debug_values with addresses should always have an op_deref.

Assisted-by: Claude Opus 4.6 (Updated tests)
2026-05-12 11:24:39 +01:00
Emil Pedersen 5c3a9a8b9a [DebugInfo] Remove DIExpr from AllocStackInst
A VarInfo within an AllocStackInst should only be used when the variable
is fully in the stack slot. Otherwise, a debug_value should be used.
2026-05-11 11:55:44 +01:00
Emil Pedersen a54a415450 Merge pull request #88838 from Snowy1803/sroa-use-debug-values
[DebugInfo] Move fragments from alloc_stack to debug_value in SILSROA
2026-05-11 11:43:30 +01:00
Augusto Noronha c906ef37a3 Merge pull request #88737 from augusto2112/fix-noncopyable-debinfo-indirection
[IRGen] Fix debug info indirection for shadow copies of moveable values
2026-05-07 11:56:37 -07:00
Emil Pedersen c3f339e957 [DebugInfo] Move fragments from alloc_stack to debug_value in SILSROA
This deprecates the use of DIExpr on alloc_stack. When varinfo is present
on an alloc_stack, it represents the whole variable. Otherwise, debug_value
should be used.
2026-05-06 11:17:50 +01:00
Emil Pedersen 4f48841b6c Merge pull request #88831 from Snowy1803/no-sil-based-debuginfo-debug-values
[DebugInfo] Invalidate alloc_stack varinfo in sil-based debuginfo
2026-05-05 20:53:56 +01:00
Emil Pedersen a95a3f9382 [DebugInfo] Invalidate alloc_stack varinfo in sil-based debuginfo
SIL-based debug info does not support debug variables. It is limited to
line tables at the IRGen level. Keeping alloc_stack variables but not
debug_values is inconsistent.
2026-05-05 15:36:57 +01:00
Aidan Hall a9cd60dd2b [SILGen] Location hints for keypath accessor thunks 2026-05-05 13:48:03 +01:00
Augusto Noronha 6364a4859b [IRGen] Fix debug info indirection for shadow copies of moveable values
When a shadow copy is emitted for an address-only value with
usesMoveableValueDebugInfo, the shadow alloca stores a pointer to the
original storage, adding a level of indirection. Since moveable values
use dbg_value instead of dbg_declare, this indirection is not implicit
and must be accounted for by setting IndirectValue. Introduce
emitShadowCopyIfNeededOrNull to distinguish whether a shadow copy was
actually created, and add the extra DW_OP_deref accordingly.
2026-04-29 12:58:04 -07:00
Joe Groff 097b0d3400 SIL: Split unchecked_*_enum_data_addr according to ownership and effects.
We cannot use spare bits or other overlapping storage layout tricks with fundamentally
address-only enums, and we can take advantage of this to do borrowing switches or other
in-place projections without copying the value. However, for resilient enums, the
implementation may use spare bit packing, but the type must be handled address-only
outside of its defining module, and we didn't have a way to express that with
borrowing switch. Optimization passes have also been running into problems with the
complexity that we were using `unchecked_take_enum_data_addr` sometimes as a pure
operation. This patch splits the instruction into three:

- `unchecked_inplace_enum_data_addr` represents a nondestructive in-place enum
  projection. It is only allowed for enums whose projection operation is
  nondestructive.
- `unchecked_take_enum_data_addr` represents a destructive enum projection,
  invalidating the enum and leaving the payload to be further consumed.
  This matches the current instruction's semantics.
- `unchecked_borrow_enum_data_addr` represents a borrowing enum projection.
  The instruction takes a second operand for "scratch" space, which the
  enum representation may be copied into in order to avoid invalidating the
  enum value, so the result is dependent on the lifetime of both the
  original enum and the scratch buffer. This allows for borrowing switches
  over resilient enums.

`unchecked_borrow_enum_data_addr` is implemented by taking advantage of the
"address-only enums can't do spare bit optimization" property at runtime.
We inspect the operand type's bitwise-borrowability from its metadata. If
the type is bitwise-borrowable, then we are allowed to bitwise-copy the
enum to the scratch space and apply the projection to the scratch space,
preserving the original value. If the type is not bitwise-borrowable, then
we cannot use spare bit optimization in its layout, so we apply the
projection in-place.

Fixes rdar://174952822.
2026-04-27 15:40:37 -07:00
Leonard Grey ffe398fe96 Merge pull request #88419 from speednoisemovement/inner_struct_name
[IRGenDebugInfo][CodeView] Name inner type member in bound generic sized containers
2026-04-21 08:53:34 -04:00
Leonard Grey 7a191e54a7 [IRGenDebugInfo][CodeView] Name inner type member in bound generic sized containers
As a workaround for issues with uniquing, bound generics are emitted as a nested structure:
- A sized outer structure with no name or identifier
- A sizeless inner structure with the mangled name as the name and no identifier.

The actual mechanism of connection for the inner and outer structures is
that the outer structure has a single unnamed member whose type is the
inner structure.

However, LLVM CodeView emission treats unnamed members as anonymous
structs and tries to inline their members into the parent. But since the
inner struct has no members, the effect is that it gets dropped.

This change names the inner struct with the mangled type name. This will
have the effect of preserving the inner struct in CodeView output, and
allow us to use a variation of the DWARF logic at
https://github.com/swiftlang/llvm-project/blob/cd1235e59b87c84144802ab85592ee75a615f231/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserSwift.cpp#L166
to recognize and handle this pattern.

More details and discussion at https://github.com/swiftlang/swift/issues/87093
2026-04-10 16:01:42 -04:00
Raphael Isemann cc72a3d04b Merge pull request #87652 from Teemperor/FixDbgInfoMem2RegAfterInline
SILMem2Reg: Fix debug scope of inlined instructions
2026-04-09 10:38:54 +01:00
Augusto Noronha 0692a56064 Merge pull request #87932 from augusto2112/emit-marker
[lldb] Encode marker annotation for protocols in debug info.
2026-04-08 08:34:09 -07:00
Augusto Noronha 69925b6a25 [DebugInfo] Emit DW_TAG_inheritance for protocol composition members
Protocol compositions like `P1 & P2` are now emitted with
DW_TAG_inheritance entries referencing each constituent protocol.
2026-04-01 15:14:13 -07:00
Meghana Gupta bc347226c2 Merge pull request #88191 from meg-gupta/nonmergeable
Use nomerge attribute to generate non-mergeable traps
2026-03-31 16:54:27 -07:00
Meghana Gupta 570721c9e0 Use nomerge attribute to generate non-mergeable traps 2026-03-31 06:37:19 -07:00
Emil Pedersen ed743259c5 [DebugInfo] [SILGen] Consider a SILLocation created from an implicit conversion of an explicit node as explicit 2026-03-30 17:52:40 +01:00
Augusto Noronha eb420df888 [lldb] Encode marker annotation for protocols in debug info.
Marker protocols are a compile time concept only, and emit no metadata.
RemoteInspection does not know how to handle existentials with these
types.

This patch emits debug info for marker protocols, so LLDB can handle
them properly before querying RemoteInspection for type information.

rdar://172847891
2026-03-25 14:18:32 -07:00
Steven Wu 12f8d9c6c9 [TEST] Switch to use new swift-driver when running tests
Default to use new swift-driver to run lit tests as legacy swift driver
is deprecated for a long time. The lit tests for legacy drivers are also
disable when running new swift-driver.

Tests that relies on legacy swift driver (for example, tests merge
module) can be enabled on conditions `legacy_swift_driver`. Fix and
split up some existing tests that relies on legacy driver.
2026-03-23 09:48:45 -07:00
Raphael Isemann 24613080f6 SILMem2Reg: Fix debug scope of debug_value for empty tuple values
Commit 0ef2094279 salvages more debug
information in Mem2Reg in several cases. It propagates the information from
the alloc_stack to the replaced load instructions.

However, there are cases where the loads from an alloca are not actually
representing loads from the respective local variable. One such case is
when there is mandatory inlining happening at the start of the pipeline.

For example, consider the example below where an identity function is inlined.
The resulting SIL will contain an alloca from the outer `result` and a load
that is the leftover after the closure (which is just a load of the passed
argument). The load that is created has its debug scope (correctly) in the
closure scope, but the loaded alloc_stack is actually the outer local variable.
The intermediate `result` that is passed to the closure is getting eliminated
by the inliner.

```
  let result = try await ... // becomes empty tuple.
  return withExtendedLifetime((...)) {
     result
  }
```

This patch forces that the scope of the debug_value describing result is
actually in the outer function and describes the right `result` local.

Fixes rdar://171023691
2026-03-19 13:04:23 +00:00
Raphael Isemann b772384527 [DebugInfo] No longer assign non-fixed-size types the size of a pointer
`CompletedDebugTypeInfo::getFromTypeInfo` currently uses the storage type as
the preferred source of size information.
For address-only types (and any other type that has no fixed size at compile
time), the storage type is always changed to a pointer.

This currently causes that some non-fixed-size types (e.g., generics)
are assigned the size of a pointer as their actual size in the generated
debug information.

For example:

```
protocol P {
associatedtype S
}

func foo<B: P>(_ b: B) {
let x: (aaa: Int, bbb: B.S?) = (aaa: 0, bbb: nil)
_ = x
let y: (Fx: Int, Fy: Int) = (Fx: 0, Fy: 0)
_ = y
}
```

results in the following DWARF output where the first struct
is given size 8 (= the size of a pointer).

```
0x000000d4:   DW_TAG_structure_type
                DW_AT_name	("$sSi3aaa_1S4main1PPQzSg3bbbtD")
                DW_AT_linkage_name	("$sSi3aaa_1S4main1PPQzSg3bbbtD")
                DW_AT_byte_size	(0x08)
                DW_AT_APPLE_runtime_class	(DW_LANG_Swift)

0x000000f3:   DW_TAG_structure_type
                DW_AT_name	("$sSi2Fx_Si2FytD")
                DW_AT_linkage_name	("$sSi2Fx_Si2FytD")
                DW_AT_byte_size	(0x10)
                DW_AT_APPLE_runtime_class	(DW_LANG_Swift)
```

This change modifies `CompletedDebugTypeInfo::getFromTypeInfo` to ignore the
storage size for types that do not have fixed size. Generics now have no
specified size or 0 in DWARF. FixedArray<A, B> without substituted type/size
is now also emitted using the dedicated FixedArray code.
2026-03-13 13:42:05 +00:00
Augusto Noronha 9a42678cd0 [DebugInfo] Emit DW_TAG_reference_type for indirect enum cases in DWARF
Wrap indirect enum case payload types in DW_TAG_reference_type to indicate
that the case stores a pointer to a heap-allocated box rather than the
payload directly.

rdar://170687015
2026-02-23 15:53:16 -08:00
Slava Pestov 85e0a9809c Merge pull request #87193 from slavapestov/valid-salvage
Sema: Add flag to force a crash if salvage() found a valid solution
2026-02-13 20:05:58 -05:00
Slava Pestov ae4f5e7c82 Run tests with -solver-enable-crash-on-valid-salvage 2026-02-13 09:57:22 -05:00
Augusto Noronha 24d1ee02f4 [DebugInfo] Emit inheritance info for generic classes with -gdwarf-types
rdar://170020164
2026-02-11 10:10:34 -08:00
Felipe de Azevedo Piovezan 7114d77a50 [DebugInfo] Relax check-next in yielding_mutate.swift
This is too strict for targets that generate authentication
instructions.
2026-02-05 08:25:12 +00:00
Felipe de Azevedo Piovezan 92191a0f4a Merge pull request #86936 from felipepiovezan/felipe/coro_line_table_issue
[IRGenSIL][DebugInfo] Fix location of Coroutine/Async exit code
2026-02-03 17:35:00 +00:00
Felipe de Azevedo Piovezan ecaa1011ca [IRGenSIL][DebugInfo] Extend lifetime of variables in coroutines
Just like in async functions, coroutines will go through the CoroSplit
flow. As such, variables in O0 need to go through the same treatment
they undergo for async functions: an `asm` directive is emitted so to
create a use of the variable after each split point.
2026-02-02 17:33:11 +00:00
Felipe de Azevedo Piovezan e14ff72d70 [IRGenSIL][DebugInfo] Fix location of Coroutine/Async exit code
Exit code should not inherit the location of the previous basic block;
instead, it should contain line zero to denote that this is not
associated with any user code.

Without this patch, stepping over code code like:

```
1. yielding mutate {
2.   yield &member_int
3.   blah
4.   blah
}
```

Would go from line 3, to line 4, to line 2.

rdar://149106144
2026-02-02 15:20:13 +00:00
Felipe de Azevedo Piovezan 559d9e5b50 [DebugInfo] Fix return debug location of borrowing accessor's second funclet
When the main IRGenSIL loop decides to use the previous instruction's
location, it does so by emitting a compiler generated location. This is
creating an issue where the return address of a borrowing accessor is
landing on such a cleanup location, making the parent frame have no line
associated with it.

Why not use the last instruction's location instead? No tests fail with
this change, and it seems to keep the literal meaning of the "use the
last location" boolean variable that already exists in code.
2026-01-30 16:29:28 +00:00
Max Desiatov 0f1dce4d1b test/DebugInfo/LoadableByAddress.swift: require PTRSIZE=64 (#86774)
This test in its current form does not pass on 32-bit platforms.
2026-01-25 08:47:34 -08:00
elsa 5e9f215f31 Merge pull request #86010 from elsakeirouz/rework-for-each-desugar
Rework ForEachStmt Desugaring
2026-01-24 13:55:51 +00:00
Max Desiatov 22e68a3aff test/DebugInfo: enable all available tests for Wasm (#86742)
Wasm is the only 32-bit platform regularly tested on Swift CI, let's enable existing `DebugInfo` tests for it.
2026-01-23 17:36:20 -08:00
Elsa Keirouz d54a572f7f [Sema] desugar ForEachStmt at AST level 2026-01-23 15:17:29 +00:00
Finagolfin e8c2005c52 [test] Disable newly failing DebugInfo async-args test case and two other unmodified regressions on 32-bit platforms 2026-01-23 17:14:49 +05:30
Adrian Prantl 974c2e77a6 Merge pull request #86653 from felipepiovezan/felipe/swift_update_tests_main
[swift] Fix DebugInfo tests to account for CoroSplit changes
2026-01-22 08:10:51 -08:00
Elsa Keirouz eedab7031a [DEBUGINFO] Tests the same things across architectures 2026-01-22 12:07:04 +00:00
Felipe de Azevedo Piovezan cb33d6da47 [swift] Fix DebugInfo tests to account for CoroSplit changes
After 9ff29a89020e in llmv-project, the async frame ptr is stored in an
alloca in entry funclets.
2026-01-20 12:21:26 +00:00
Hamish Knight df187348bc [test] Add some extra for loop tests
Add some test cases that were uncovered when doing source compatibility
testing for the for loop rework.
2026-01-18 23:25:52 +00:00