Skip to content

Commit bd3b451

Browse files
committed
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.
1 parent 76ebaee commit bd3b451

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

lib/RemoteAST/RemoteAST.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,18 @@ class RemoteASTContextConcreteImpl final : public RemoteASTContextImpl {
509509
Reader.readTypeFromMetadata(metadataAddress.getAddressData());
510510
if (!typeResult)
511511
return getFailure<std::pair<Type, RemoteAddress>>();
512+
513+
// When the existential wraps a class type, LLDB expects that the
514+
// address returned is the class instance itself and not the address
515+
// of the reference.
516+
if (!isBridged && typeResult->getClassOrBoundGenericClass()) {
517+
auto pointerval = Reader.readPointerValue(valueAddress.getAddressData());
518+
if (!pointerval)
519+
return getFailure<std::pair<Type, RemoteAddress>>();
520+
521+
valueAddress = RemoteAddress(*pointerval);
522+
}
523+
512524
return std::make_pair<Type, RemoteAddress>(std::move(typeResult),
513525
std::move(valueAddress));
514526
}
@@ -525,6 +537,18 @@ class RemoteASTContextConcreteImpl final : public RemoteASTContextImpl {
525537
Reader.readTypeFromMetadata(metadataAddress.getAddressData());
526538
if (!typeResult)
527539
return getFailure<std::pair<Type, RemoteAddress>>();
540+
541+
// When the existential wraps a class type, LLDB expects that the
542+
// address returned is the class instance itself and not the address
543+
// of the reference.
544+
if (typeResult->getClassOrBoundGenericClass()) {
545+
auto pointerval = Reader.readPointerValue(valueAddress.getAddressData());
546+
if (!pointerval)
547+
return getFailure<std::pair<Type, RemoteAddress>>();
548+
549+
valueAddress = RemoteAddress(*pointerval);
550+
}
551+
528552
return std::make_pair<Type, RemoteAddress>(std::move(typeResult),
529553
std::move(valueAddress));
530554
}

0 commit comments

Comments
 (0)