<rdar://problem/11485744> Implement important data formatters in C++. Have the Objective-C language runtime plugin expose class descriptors objects akin to the objc_runtime.py Pythonic implementation. Rewrite the data formatters for some core Cocoa classes in C++ instead of Python.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@163155 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/ObjCLanguageRuntime.cpp b/source/Target/ObjCLanguageRuntime.cpp
index c41db3c..a404ce4 100644
--- a/source/Target/ObjCLanguageRuntime.cpp
+++ b/source/Target/ObjCLanguageRuntime.cpp
@@ -262,3 +262,85 @@
}
return result;
}
+
+bool
+ObjCLanguageRuntime::ClassDescriptor::IsPointerValid (lldb::addr_t value,
+ uint32_t ptr_size,
+ bool allow_NULLs,
+ bool allow_tagged,
+ bool check_version_specific)
+{
+ if (!value)
+ return allow_NULLs;
+ if ( (value % 2) == 1 && allow_tagged)
+ return true;
+ if ((value % ptr_size) == 0)
+ return (check_version_specific ? CheckPointer(value,ptr_size) : true);
+ else
+ return false;
+}
+
+ObjCLanguageRuntime::ObjCISA
+ObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa)
+{
+ if (!IsValidISA(isa))
+ return 0;
+
+ ISAToDescriptorIterator found = m_isa_to_descriptor_cache.find(isa);
+ ISAToDescriptorIterator end = m_isa_to_descriptor_cache.end();
+
+ if (found != end && found->second)
+ {
+ ClassDescriptorSP superclass = found->second->GetSuperclass();
+ if (!superclass || !superclass->IsValid())
+ return 0;
+ else
+ {
+ ObjCISA parent_isa = superclass->GetISA();
+ m_isa_to_descriptor_cache[parent_isa] = superclass;
+ return parent_isa;
+ }
+ }
+
+ ClassDescriptorSP descriptor(GetClassDescriptor(isa));
+ if (!descriptor.get() || !descriptor->IsValid())
+ return 0;
+ m_isa_to_descriptor_cache[isa] = descriptor;
+ ClassDescriptorSP superclass(descriptor->GetSuperclass());
+ if (!superclass.get() || !superclass->IsValid())
+ return 0;
+ ObjCISA parent_isa = superclass->GetISA();
+ m_isa_to_descriptor_cache[parent_isa] = superclass;
+ return parent_isa;
+}
+
+// TODO: should we have a transparent_kvo parameter here to say if we
+// want to replace the KVO swizzled class with the actual user-level type?
+ConstString
+ObjCLanguageRuntime::GetActualTypeName(ObjCLanguageRuntime::ObjCISA isa)
+{
+ static const ConstString g_unknown ("unknown");
+
+ if (!IsValidISA(isa))
+ return ConstString();
+
+ ISAToDescriptorIterator found = m_isa_to_descriptor_cache.find(isa);
+ ISAToDescriptorIterator end = m_isa_to_descriptor_cache.end();
+
+ if (found != end && found->second)
+ return found->second->GetClassName();
+
+ ClassDescriptorSP descriptor(GetClassDescriptor(isa));
+ if (!descriptor.get() || !descriptor->IsValid())
+ return ConstString();
+ ConstString class_name = descriptor->GetClassName();
+ if (descriptor->IsKVO())
+ {
+ ClassDescriptorSP superclass(descriptor->GetSuperclass());
+ if (!superclass.get() || !superclass->IsValid())
+ return ConstString();
+ descriptor = superclass;
+ }
+ m_isa_to_descriptor_cache[isa] = descriptor;
+ return descriptor->GetClassName();
+}