kastiglione created this revision. kastiglione added reviewers: aprantl, jingham, augusto2112. Herald added a project: All. kastiglione requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
Classes implemented in Swift can be exposed to ObjC. For those classes, the ObjC metadata is incomplete (the types of the ivars are incomplete), but as one would expect the Swift metadata is complete. In such cases, the Swift runtime should be consulted first when determining the dynamic type of a value. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D152837 Files: lldb/source/Core/ValueObjectDynamicValue.cpp lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
Index: lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h =================================================================== --- lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h +++ 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 Index: lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h =================================================================== --- lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h +++ 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, Index: lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp =================================================================== --- lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp +++ 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_t> 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(); } Index: lldb/source/Core/ValueObjectDynamicValue.cpp =================================================================== --- lldb/source/Core/ValueObjectDynamicValue.cpp +++ 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<ObjCLanguageRuntime>( + 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);
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits