[Lldb-commits] [lldb] e19339f - [lldb] Identify Swift-implemented ObjC classes
Dave Lee via lldb-commits
lldb-commits at lists.llvm.org
Thu Jul 20 19:32:18 PDT 2023
Author: Dave Lee
Date: 2023-07-20T19:32:12-07:00
New Revision: e19339f5f8c15d4307aaed14309e38e3c87121ac
URL: https://github.com/llvm/llvm-project/commit/e19339f5f8c15d4307aaed14309e38e3c87121ac
DIFF: https://github.com/llvm/llvm-project/commit/e19339f5f8c15d4307aaed14309e38e3c87121ac.diff
LOG: [lldb] Identify Swift-implemented ObjC classes
Classes implemented in Swift can be exposed to ObjC. For those classes, the ObjC
metadata is incomplete. Specifically, the encoded types of the ivars are incomplete. As
one might expect, the Swift metadata _is_ complete. In such cases, the Swift runtime
should be consulted when determining the dynamic type of a value.
Differential Revision: https://reviews.llvm.org/D152837
Added:
Modified:
lldb/include/lldb/Target/LanguageRuntime.h
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/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
Removed:
################################################################################
diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h
index 9cc79dc976c4d8..eff79a0bf0d062 100644
--- a/lldb/include/lldb/Target/LanguageRuntime.h
+++ b/lldb/include/lldb/Target/LanguageRuntime.h
@@ -67,6 +67,12 @@ class LanguageRuntime : public Runtime, public PluginInterface {
virtual lldb::LanguageType GetLanguageType() const = 0;
+ /// Return the preferred language runtime instance, which in most cases will
+ /// be the current instance.
+ virtual LanguageRuntime *GetPreferredLanguageRuntime(ValueObject &in_value) {
+ return nullptr;
+ }
+
virtual bool GetObjectDescription(Stream &str, ValueObject &object) = 0;
virtual bool GetObjectDescription(Stream &str, Value &value,
diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp
index 9db50aeeec9eaa..e6e30dce9d1e4a 100644
--- a/lldb/source/Core/ValueObjectDynamicValue.cpp
+++ b/lldb/source/Core/ValueObjectDynamicValue.cpp
@@ -149,7 +149,18 @@ bool ValueObjectDynamicValue::UpdateValue() {
if (known_type != lldb::eLanguageTypeUnknown &&
known_type != lldb::eLanguageTypeC) {
runtime = process->GetLanguageRuntime(known_type);
- if (runtime)
+ if (auto *preferred_runtime =
+ runtime->GetPreferredLanguageRuntime(*m_parent)) {
+ // Try the preferred runtime first.
+ found_dynamic_type = preferred_runtime->GetDynamicTypeAndAddress(
+ *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
+ value_type);
+ if (found_dynamic_type)
+ // Set the operative `runtime` for later use in this function.
+ runtime = preferred_runtime;
+ }
+ if (!found_dynamic_type)
+ // Fallback to the runtime for `known_type`.
found_dynamic_type = runtime->GetDynamicTypeAndAddress(
*m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
value_type);
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index 80ba352228c543..39969520b74556 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -10,8 +10,10 @@
#include "lldb/Expression/FunctionCaller.h"
#include "lldb/Target/ABI.h"
+#include "lldb/Target/Language.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
+#include "lldb/lldb-enumerations.h"
using namespace lldb;
using namespace lldb_private;
@@ -668,6 +670,19 @@ uint64_t ClassDescriptorV2::GetInstanceSize() {
return 0;
}
+// From the ObjC runtime.
+static uint8_t IS_SWIFT_STABLE = 1U << 1;
+
+LanguageType ClassDescriptorV2::GetImplementationLanguage() const {
+ std::unique_ptr<objc_class_t> objc_class;
+ if (auto *process = m_runtime.GetProcess())
+ if (Read_objc_class(process, objc_class))
+ if (objc_class->m_flags & IS_SWIFT_STABLE)
+ return lldb::eLanguageTypeSwift;
+
+ return lldb::eLanguageTypeObjC;
+}
+
ClassDescriptorV2::iVarsStorage::iVarsStorage() : m_ivars(), m_mutex() {}
size_t ClassDescriptorV2::iVarsStorage::size() { return m_ivars.size(); }
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
index 09e5383d7fb95a..d298af92ba5e62 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
@@ -12,6 +12,7 @@
#include <mutex>
#include "AppleObjCRuntimeV2.h"
+#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private.h"
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
@@ -34,6 +35,8 @@ class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor {
return true; // any Objective-C v2 runtime class descriptor we vend is valid
}
+ lldb::LanguageType GetImplementationLanguage() 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/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index a2e1c8e54dd4e5..d5357b94d68edc 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -33,6 +33,7 @@
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -753,6 +754,19 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
RegisterObjCExceptionRecognizer(process);
}
+LanguageRuntime *
+AppleObjCRuntimeV2::GetPreferredLanguageRuntime(ValueObject &in_value) {
+ if (auto process_sp = in_value.GetProcessSP()) {
+ assert(process_sp.get() == m_process);
+ if (auto descriptor_sp = GetNonKVOClassDescriptor(in_value)) {
+ LanguageType impl_lang = descriptor_sp->GetImplementationLanguage();
+ if (impl_lang != eLanguageTypeUnknown)
+ return process_sp->GetLanguageRuntime(impl_lang);
+ }
+ }
+ return nullptr;
+}
+
bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress(
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name, Address &address,
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
index da30d8135f6d42..678865ecd9186f 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
@@ -38,6 +38,8 @@ class AppleObjCRuntimeV2 : public AppleObjCRuntime {
static llvm::StringRef GetPluginNameStatic() { return "apple-objc-v2"; }
+ LanguageRuntime *GetPreferredLanguageRuntime(ValueObject &in_value) override;
+
static char ID;
bool isA(const void *ClassID) const override {
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
index f51abe4b62f4a4..0a8b6e8d56ed06 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
@@ -24,6 +24,7 @@
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/ThreadSafeDenseMap.h"
+#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private.h"
class CommandObjectObjC_ClassTable_Dump;
@@ -86,6 +87,11 @@ class ObjCLanguageRuntime : public LanguageRuntime {
return (m_is_cf == eLazyBoolYes);
}
+ /// Determine whether this class is implemented in Swift.
+ virtual lldb::LanguageType GetImplementationLanguage() const {
+ return lldb::eLanguageTypeObjC;
+ }
+
virtual bool IsValid() = 0;
/// There are two routines in the ObjC runtime that tagged pointer clients
More information about the lldb-commits
mailing list