mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
RemoteAST: More consistent behavior of existentials inside classes
LLDB calls getDynamicTypeAndAddressForExistential() on an existential value without knowing if its a class existential or opaque existential. Class existentials return the address of the instance itself here, whereas opaque existentials always returned the address of the payload value. This meant the caller could not usefully operate on the payload value if it was of class type, because there was no way of knowing if the extra dereference had occurred or not. Now, always load the reference if the wrapped type is a class, even if the existential is opaque. Will be tested on the lldb side with another change I'm working on.
This commit is contained in:
@@ -509,6 +509,18 @@ public:
|
||||
Reader.readTypeFromMetadata(metadataAddress.getAddressData());
|
||||
if (!typeResult)
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
|
||||
// When the existential wraps a class type, LLDB expects that the
|
||||
// address returned is the class instance itself and not the address
|
||||
// of the reference.
|
||||
if (!isBridged && typeResult->getClassOrBoundGenericClass()) {
|
||||
auto pointerval = Reader.readPointerValue(valueAddress.getAddressData());
|
||||
if (!pointerval)
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
|
||||
valueAddress = RemoteAddress(*pointerval);
|
||||
}
|
||||
|
||||
return std::make_pair<Type, RemoteAddress>(std::move(typeResult),
|
||||
std::move(valueAddress));
|
||||
}
|
||||
@@ -525,6 +537,18 @@ public:
|
||||
Reader.readTypeFromMetadata(metadataAddress.getAddressData());
|
||||
if (!typeResult)
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
|
||||
// When the existential wraps a class type, LLDB expects that the
|
||||
// address returned is the class instance itself and not the address
|
||||
// of the reference.
|
||||
if (typeResult->getClassOrBoundGenericClass()) {
|
||||
auto pointerval = Reader.readPointerValue(valueAddress.getAddressData());
|
||||
if (!pointerval)
|
||||
return getFailure<std::pair<Type, RemoteAddress>>();
|
||||
|
||||
valueAddress = RemoteAddress(*pointerval);
|
||||
}
|
||||
|
||||
return std::make_pair<Type, RemoteAddress>(std::move(typeResult),
|
||||
std::move(valueAddress));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user