diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp --- a/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/ValueObjectDynamicValue.h" +#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/CompilerType.h" @@ -108,6 +109,22 @@ return m_parent->GetValueType(); } +static bool UseSwiftRuntime(ValueObject &valobj, + const ExecutionContext &exe_ctx) { + if (auto *frame = exe_ctx.GetFramePtr()) + if (frame->GetLanguage() == lldb::eLanguageTypeSwift) + return true; + + if (auto *process = exe_ctx.GetProcessPtr()) + if (auto *runtime = llvm::dyn_cast_or_null( + process->GetLanguageRuntime(lldb::eLanguageTypeObjC))) + if (auto class_sp = runtime->GetClassDescriptor(valobj)) + if (class_sp->IsSwift()) + return true; + + return false; +} + bool ValueObjectDynamicValue::UpdateValue() { SetValueIsValid(false); m_error.Clear(); @@ -146,6 +163,17 @@ LanguageRuntime *runtime = nullptr; lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage(); + + // An ObjC object in a Swift context, or a ObjC object implemented in Swift. + if (known_type == lldb::eLanguageTypeObjC && + UseSwiftRuntime(*m_parent, exe_ctx)) { + runtime = process->GetLanguageRuntime(lldb::eLanguageTypeSwift); + if (runtime) + found_dynamic_type = runtime->GetDynamicTypeAndAddress( + *m_parent, m_use_dynamic, class_type_or_name, dynamic_address, + value_type); + } + if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC) { runtime = process->GetLanguageRuntime(known_type); diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h @@ -34,6 +34,8 @@ return true; // any Objective-C v2 runtime class descriptor we vend is valid } + bool IsSwift() const override; + // a custom descriptor is used for tagged pointers bool GetTaggedPointerInfo(uint64_t *info_bits = nullptr, uint64_t *value_bits = nullptr, diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp @@ -530,6 +530,18 @@ return 0; } +// From the ObjC runtime. +static uint8_t IS_SWIFT_STABLE = 1U << 1; + +bool ClassDescriptorV2::IsSwift() const { + std::unique_ptr objc_class; + if (auto *process = m_runtime.GetProcess()) + if (Read_objc_class(process, objc_class)) + return objc_class->m_flags & IS_SWIFT_STABLE; + + return false; +} + ClassDescriptorV2::iVarsStorage::iVarsStorage() : m_ivars(), m_mutex() {} size_t ClassDescriptorV2::iVarsStorage::size() { return m_ivars.size(); } diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h --- a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h @@ -86,6 +86,8 @@ return (m_is_cf == eLazyBoolYes); } + virtual bool IsSwift() const { return false; } + virtual bool IsValid() = 0; /// There are two routines in the ObjC runtime that tagged pointer clients