When a typealias or associated type is declared inside a protocol, the
mangling of an access like S.A (for `typealias A` in `protocol P` and
`struct S : P`) wraps the protocol in a BoundGenericProtocol whose
single generic argument is the conforming Self type:
BoundGenericProtocol
|
--> Protocol: P
|
--> TypeList:
|
--> Structure: S
DemanglingForTypeRef was substituting the richer parent wholesale in
place of the Protocol, losing the BoundGenericProtocol entirely and
producing a mangled tree that looks as if A were declared directly
on S rather than inside P.
Assisted-by: claude
rdar://160408523
Typically, the first node of a nested type is the type that contains it.
For example:
```
Demangling for $s7ModBase5OuterV5InnerC
kind=Global
kind=Class
kind=Structure
kind=Module, text="ModBase"
kind=Identifier, text="Outer"
kind=Identifier, text="Inner"
$s7ModBase5OuterV5InnerC ---> ModBase.Outer.Inner
```
However, when a type is declared inside an extension of "Outer", that
becomes part of the mangled name too. For example:
```
Demangling for $s7ModBase5OuterV6ModExtE5InnerC
kind=Global
kind=Class
kind=Extension
kind=Module, text="ModExt"
kind=Structure
kind=Module, text="ModBase"
kind=Identifier, text="Outer"
kind=Identifier, text="Inner"
$s7ModBase5OuterV6ModExtE5InnerC ---> (extension in ModExt):ModBase.Outer.Inner
````
DemanglingForTypeRef did not treat the extension case correctly, and was
losing the extension information. This patch fixes it.
Assisted-by: claude
rdar://176586425
RemoteInspection was failing to produce type info for metatypes of
constrained existentials (any SomeType<ConstraintHere>.Type)
A constrained existential has the same layout as a regular protocol
composition, so we can use that instead.
rdar://176586637
rebuildStorageTypeInfo only handled ReferenceTypeInfo and
RecordKind::ClassExistential inner types for unmanaged_storage, but
failed for imported unmanaged types which are imported behind a
pointer (which is a struct).
rdar://175379963
EnumTypeInfoBuilder will build FieldInfos of indirect enum payloads with
the TypeRef set to Builtin.NativeObject.
EnumTypeInfoBuilder has access to the typeref of the type behind the
pointer, which currently isn't saved anywhere.
RemoteInspection clients like LLDB have to re-query it, and read
metadata to find out what the type behind the reference it.
This patch adds a field to FieldInfo with the payload TypeRef, the
one behind the reference.
rdar://170684760
Plumb the `BitwiseBorrowable` and `AddressableForDependencies` layout
properties through reflection TypeLowering, and implement type layout
for `Builtin.Borrow` based on those properties.
There is an existing cache which is built when looking up
FieldDescriptors. collectAllConformances ignored this cache and would
parse every FieldDescriptor again. Use the existing cache mechanism.
rdar://166098516
We scan the target's initial allocation pool, and all 16kB heap allocations. We check each pointer-aligned offset within those areas, and try to read it as Swift metadata and get a name from it. If that fails, quietly move on. It's very unlikely for some random memory to look enough like Swift metadata for this to produce a name, so this works very well to print the generic metadata instantiated in the remote process without requiring `SWIFT_DEBUG_ENABLE_METADATA_ALLOCATION_ITERATION`.
rdar://161120936
This patch adds a new SymbolicExtendedExistentialTypeRef kind, and
wires it up in TypeDecoder, TypeRefBuilder, TypeLowering, and
ASTDemangler.
This is tested indirectly via the matching LLDB commit.
Add an extra opaque field to AddressSpace, which can be used by clients
of RemoteInspection to distinguish between different address spaces.
LLDB employs an optimization where it reads memory from files instead of
the running process whenever it can to speed up memory reads (these can
be slow when debugging something over a network). To do this, it needs
to keep track whether an address originated from a process or a file. It
currently distinguishes addresses by setting an unused high bit on the
address, but because of pointer authentication this is not a reliable
solution. In order to keep this optimization working, this patch adds an
extra opaque AddressSpace field to RemoteAddress, which LLDB can use on
its own implementation of MemoryReader to distinguish between addresses.
This patch is NFC for the other RemoteInspection clients, as it adds
extra information to RemoteAddress, which is entirely optional and if
unused should not change the behavior of the library.
Although this patch is quite big the changes are largely mechanical,
replacing threading StoredPointer with RemoteAddress.
rdar://148361743
Reflection metadata lookup failures are notoriously difficult to debug
because there is no error handling in TypeLowering outside of
compile-time #ifdef'd fprintf(stderr) calls. The nicest thing to do
would be to adopt llvm::Expected<> but TypeLowering is also included
in the standard library, which only has access to a tiny subset of the
LLVM Support library. This patch adds a place to store a pointer to
the first encountered error, which can then be converted to an
llvm::Error at the API level.
Fixes the immediate problem, but the presence of demangling code in the
runtime means that we'll need a follow-up to fix the compiler so that it
doesn't try to use the demangler to materialize metadata for function types
that have both isolation and a sending result.
rdar://142443925
To determine the correct enum layout, we first count various
categories of cases. Before, we counted indirect generic cases as
"generic", but regular "generic" cases can't export spare bits.
Change this to count "indirect" cases as a separate category.
In particular, this ensures that fully-indirect enums use
spare bits from the pointers even when some or all of the cases
are generic.
Resolves rdar://133890406
The first word in a class existential is the class pointer itself.
This pointer exposes spare bits differently depending
on the platform, which becomes apparent when you try to reflect
an Optional carrying such an MPE.
Add new test cases and some logic to zero out the first
word of spare bit information only on platforms with 8-byte pointers.
Class existentials expose spare bits from all of the pointers, not just the first one.
Due to a bad bug here, we were properly exposing spare bits from the first pointer,
but then claiming that all bits of subsequent pointers were spare.
This accidentally resulted in the correct operation on 64-bit targets
(it picked the highest-order spare bit, which happened to be spare
in both the broken mask and the correct mask). But on 32-bit targets,
this exposed the high-order bits of pointers, which is incorrect.
Expand the test a bit while we're here as well.
Resolves rdar://132715829
This plugs a hole where we failed to recognize a CF type when it
appeared as the payload of an enum stored as a property. Curiously,
RemoteMirror is able to reflect this when the enum appears by itself,
just not when it's stored as a property.
The simplest fix is to hook into the TypeInfo calculation which
computes a TypeInfo (basically, the tree of fields) from a TypeRef
(basically, the name of the type, including generic context).
Specifically, we sometimes end up here with a "type alias" that
none of the lookup support seems to be able to handle. Fortunately,
these aliases demangle into a pretty predictable shape, so this
just pattern-matches the specific demangle tree shape to recognize
these as "type aliases in the `__C` module whose name starts with `CF`
and ends with `Ref`".
Resolves rdar://82465109
UnsafeContinuations can be stored in variables or properties,
so it's important for RemoteMirror to be able to at least minimally
recognize them.
This just treats an UnsafeContinuation as a refcounted pointer.
Which might be "good enough" for now.
Working towards rdar://110351406
The "generic depth" is used to match up generic type variables.
For example:
```
struct Foo<T> { // `T` at generic depth 0
struct Bar {
struct Baz<U> { // 'U' at generic depth 1
...
}}}
```
Note in the above that `Bar` is not counted in the
generic depth. The previous logic did count `Bar` in
the generic depth calculation, leading to mismatches
when trying to associate references to generic variables.
This adds a new test with cases like the above and of course
corrects the calculation.
Resolves rdar://127450037
This fills in a number of missing cases:
* MPEs with closure payloads
* MPEs with many non-payload cases
* MPEs with class existential payloads
* MPEs with existential metatype payloads
Resolves rdar://132270733
Resolves rdar://128705332