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

Reply via email to