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:
Slava Pestov
2019-02-10 16:56:14 -05:00
parent 76ebaee078
commit bd3b45138f

View File

@@ -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));
}