When a struct has stored properties from an internal bridging header,
add @_hasHiddenStoredProperties to force address-only on both library
and client sides, and resolve layout via the defining module's
HiddenTypeLayouts table in IRGen.
Making these structs loadable is challenging because library and client
must agree on the register-passing scheme (which registers carry which
fields), and that scheme depends on the full type structure that the
client cannot see. Address-only sidesteps this by passing everything
indirectly.
Tests: hidden-type-irgen.swift verifies the Client's IR has correct
alloca sizes/alignments and outlined copy witnesses without referencing
hidden C symbols. hidden-type-runtime.swift builds a dylib + executable
and verifies values round-trip correctly across the boundary at runtime.
`ASTDemangler` drops LifetimeDependenceInfo (see `ASTDemangler.cpp`'s "Handle LifetimeDependenceInfo here" TODO); until that TODO is closed, types containing function types with lifetime dependencies cannot round-trip.
Resolves https://github.com/swiftlang/swift/issues/89257
rdar://177437498
Since salvageDebugInfo now uses debug reconstruction basic blocks,
the plus, minus, and constant SILDebugInfoExpression operators were
left unused. This commit removes them, and updates some of their tests
to use debug basic blocks.
Assisted-by: Claude
HiddenType is a new TypeBase subclass that carries a mangled name
without leaking the actual type definition. It serves as a type-slot
placeholder for stored-property types that have been elided from a
serialized binary module, so that the client side can either
(1) resolve this mangled name to the real type if the client has access to the owning module, or
(2) use the mangled name as a key to query abstract layout information also serialized in the binary module.
As an example — a library with a hidden field of a bridging-imported type:
```
// Utility.h (internal bridging header)
// typedef struct { int value; } Wrapper;
public struct S {
private var w: Wrapper
public var weight: Double
}
In the serialized module, the client's view reconstructs as:
public struct S {
private var w: @_hidden("$sSo7Wrappera")
public var weight: Double
}
```
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
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
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
These will be used internally by the type checker to represent bindings
that are the joins and meets of types involving type variables. They
will not appear anywhere outside of the bindings code---so you won't
see them in expressions, or matchTypes(), etc.
`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.
Fix the debug info emitted for bridging header PCH when compilation
caching is used. This includes:
* Bridging header should have the correct dwo_name that uses CASID
* The search_path for PCH should be the cache key that can load the PCH
just like other modules.
Add flag `-debug-module-cache-key` and flag `-debug-module-self-key` to
support embedded swift module output in the debug info via CASID.
rdar://169110002
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
After https://github.com/swiftlang/swift/pull/85655, DI types for
existential typealiases and their inner protocol types are created,
which may encounter conflicts in the DIRefMap cache and assert failures
because they can have identical mangled names. This change fixes this
issue by using a separate cache for existential typealiases to avoid
such conflicts.
Issue https://github.com/swiftlang/swift/issues/86313
This updates a large number of internal symbols, function names,
and types to match the final approved terminology. Matching the
surface language terminology and the compiler internals should
make the code easier for people to understand into the future.
When using compilation caching, make sure the debug info emitted in the
swift TU references PCM files via CASID instead of file path. This
allows dsymutil and lldb to load clang modules correctly from CAS,
instead of relying on file system to load the file.
rdar://167054494
We had introduced coroframe_entry downstream while the upstream proposal
was discussed. It has since been merged upstream, so this commit changes
the code to use the upstream intrisic, avoiding a binary incompatibility
in the IR w.r.t. upstream.
Previously debug info made not difference between an existential type and a
protocol type. This caused us to loose typealiases such as
typealias Alias = ProtocolType
in the debug info.
rdar://161134092
We currently disallow these by deleting them in the `swift` namespace.
This approach has several loopholes, all of which ultimately work
because we happen to define specializations of `simplify_type` for
`swift::Type`:
* `llvm::isa/cast/dyn_cast`. The deleted partial specializations will
not be selected because they are not defined in the `llvm` namespace.
* The argument is a non-const `Type`. The deleted function templates
will not be selected because they all accept a `const Type &`, and
there is a better `Y &Val` partial specialization in LLVM.
* Other casting function templates such as `isa_and_nonull` and
`cast_if_present` are not deleted.
Eliminate these loopholes by instead triggering a static assertion
failure with a helpful message upon instantiation of `CastInfo` for
`swift::Type`.
This new option allows the Driver to pass the path to a compilation
job's own binary swiftmodule artifact to the frontend. The compiler
then stores this path in the debug info, to allow clients like LLDB to
unambiguously know which binary Swift module belongs to which compile
unit.
rdar://163302154
This is currently not wired up to anything. I am going to wire it up in
subsequent commits.
The reason why we are introducing this new Builtin type is to represent that we
are going to start stealing bits from the protocol witness table pointer of the
Optional<any Actor> that this type is bitwise compatible with. The type will
ensure that this value is only used in places where we know that it will be
properly masked out giving us certainty that this value will not be used in any
manner without it first being bit cleared and transformed back to Optional<any
Actor>.
For swift async debug info, we create llvm.dbg.declare that contain
locations which may not be a pointer or int. This is fine, because the
CoroSplitter pass fixes up those llvm.dbg.declares later.
However, with a recent change to the LLVM Verifier, there is a check
that asserts if there is a llvm.dbg.declare with a location other than
a pointer or an int.
To workaround the problem, we created a new llvm.dbg.coroframe_entry
intrinsic that doesn't have the same restriction as llvm.dbg.declare.
This patch ensures that in async code, we now emit the new
llvm.dbg.coroframe_entry intrinsic, instead of llvm.dbg.declare
intrinsic
rdar://157299589
rdar://157509307