[Lldb-commits] [lldb] r164808 - in /lldb/trunk: include/lldb/Target/ObjCLanguageRuntime.h source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp
Sean Callanan
scallanan at apple.com
Thu Sep 27 16:47:51 PDT 2012
Author: spyffe
Date: Thu Sep 27 18:47:51 2012
New Revision: 164808
URL: http://llvm.org/viewvc/llvm-project?rev=164808&view=rev
Log:
Improved the runtime reading to also get data
out of the metaclass, so as to enumerate class
methods for an object.
Modified:
lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp
Modified: lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h?rev=164808&r1=164807&r2=164808&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h Thu Sep 27 18:47:51 2012
@@ -119,7 +119,8 @@
// This should return true iff the interface could be completed
virtual bool
Describe (std::function <void (ObjCISA)> const &superclass_func,
- std::function <void (const char*, const char*)> const &method_func)
+ std::function <void (const char*, const char*)> const &instance_method_func,
+ std::function <void (const char*, const char*)> const &class_method_func)
{
return false;
}
Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=164808&r1=164807&r2=164808&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Thu Sep 27 18:47:51 2012
@@ -973,7 +973,8 @@
class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor
{
public:
- ClassDescriptorV2 (ValueObject &ptr_to_object)
+ ClassDescriptorV2 (ObjCLanguageRuntime &runtime, ValueObject &ptr_to_object) :
+ m_runtime(runtime)
{
lldb::addr_t object_la = ptr_to_object.GetValueAsUnsigned(0);
lldb::ProcessSP process_sp = ptr_to_object.GetProcessSP();
@@ -988,7 +989,8 @@
Initialize (isa, process_sp);
}
- ClassDescriptorV2 (ObjCLanguageRuntime::ObjCISA isa, lldb::ProcessSP process_sp)
+ ClassDescriptorV2 (ObjCLanguageRuntime &runtime, ObjCLanguageRuntime::ObjCISA isa, lldb::ProcessSP process_sp) :
+ m_runtime(runtime)
{
Initialize (isa, process_sp);
}
@@ -1008,10 +1010,7 @@
if (!m_valid)
return ObjCLanguageRuntime::ClassDescriptorSP();
- ProcessSP process_sp = m_process_wp.lock();
- if (!process_sp)
- return ObjCLanguageRuntime::ClassDescriptorSP();
- return AppleObjCRuntime::ClassDescriptorSP(new ClassDescriptorV2(m_objc_class.m_superclass,process_sp));
+ return m_runtime.GetClassDescriptor(m_objc_class.m_superclass);
}
virtual bool
@@ -1046,7 +1045,8 @@
virtual bool
Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
- std::function <void (const char *, const char *)> const &method_func)
+ std::function <void (const char *, const char *)> const &instance_method_func,
+ std::function <void (const char *, const char *)> const &class_method_func)
{
if (!m_valid)
return false;
@@ -1075,28 +1075,47 @@
if (!ro->Read(process_sp, m_objc_class.m_data_la))
return false;
}
+
+ static ConstString NSObject_name("NSObject");
- superclass_func(m_objc_class.m_superclass);
-
- std::auto_ptr <method_list_t> base_method_list;
-
- base_method_list.reset(new method_list_t);
- if (!base_method_list->Read(process_sp, ro->m_baseMethods_la))
- return false;
-
- if (base_method_list->m_entsize != method_t::GetSize(process_sp))
- return false;
-
- std::auto_ptr <method_t> method;
- method.reset(new method_t);
+ if (m_name != NSObject_name && superclass_func)
+ superclass_func(m_objc_class.m_superclass);
- for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i)
+ if (instance_method_func)
{
- method->Read(process_sp, base_method_list->m_first_la + (i * base_method_list->m_entsize));
+ std::auto_ptr <method_list_t> base_method_list;
+
+ base_method_list.reset(new method_list_t);
+ if (!base_method_list->Read(process_sp, ro->m_baseMethods_la))
+ return false;
- method_func(method->m_name.c_str(), method->m_types.c_str());
+ if (base_method_list->m_entsize != method_t::GetSize(process_sp))
+ return false;
+
+ std::auto_ptr <method_t> method;
+ method.reset(new method_t);
+
+ for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i)
+ {
+ method->Read(process_sp, base_method_list->m_first_la + (i * base_method_list->m_entsize));
+
+ instance_method_func(method->m_name.c_str(), method->m_types.c_str());
+ }
}
+ if (class_method_func)
+ {
+ ObjCLanguageRuntime::ClassDescriptorSP metaclass = m_runtime.GetClassDescriptor(m_objc_class.m_isa);
+
+ // We don't care about the metaclass's superclass, or its class methods. Its instance methods are
+ // our class methods.
+
+ metaclass->Describe(std::function <void (ObjCLanguageRuntime::ObjCISA)> (nullptr),
+ class_method_func,
+ std::function <void (const char *, const char *)> (nullptr));
+ }
+ while (0);
+
return true;
}
@@ -1254,6 +1273,7 @@
private:
static const uint32_t RW_REALIZED = (1 << 31);
+ ObjCLanguageRuntime &m_runtime; // The runtime, so we can read our metaclass.
bool m_valid; // Gates whether we trust anything here at all.
lldb::addr_t m_objc_class_la; // The address of the objc_class_t.
@@ -1715,7 +1735,7 @@
if (found != end && found->second)
return found->second;
- ClassDescriptorSP descriptor = ClassDescriptorSP(new ClassDescriptorV2(isa,m_process->CalculateProcess()));
+ ClassDescriptorSP descriptor = ClassDescriptorSP(new ClassDescriptorV2(*this, isa, m_process->CalculateProcess()));
if (descriptor && descriptor->IsValid())
m_isa_to_descriptor_cache[descriptor->GetISA()] = descriptor;
return descriptor;
@@ -1740,7 +1760,7 @@
if (ptr_value & 1)
return ClassDescriptorSP(new ClassDescriptorV2Tagged(in_value)); // do not save tagged pointers
- descriptor = ClassDescriptorSP(new ClassDescriptorV2(in_value));
+ descriptor = ClassDescriptorSP(new ClassDescriptorV2(*this, in_value));
if (descriptor && descriptor->IsValid())
m_isa_to_descriptor_cache[descriptor->GetISA()] = descriptor;
@@ -1832,7 +1852,7 @@
if (m_isa_to_descriptor_cache.count(elt.second))
continue;
- ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(elt.second, process_sp));
+ ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, elt.second, process_sp));
if (log && log->GetVerbose())
log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%llx (%s) from dynamic table to isa->descriptor cache", elt.second, elt.first.AsCString());
@@ -1878,7 +1898,7 @@
if (m_isa_to_descriptor_cache.count(objc_isa))
continue;
- ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(objc_isa, process_sp));
+ ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, objc_isa, process_sp));
if (log && log->GetVerbose())
log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%llx (%s) from static table to isa->descriptor cache", objc_isa, descriptor_sp->GetClassName().AsCString());
Modified: lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp?rev=164808&r1=164807&r2=164808&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp (original)
+++ lldb/trunk/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp Thu Sep 27 18:47:51 2012
@@ -194,10 +194,7 @@
m_external_source->SetMetadata((uintptr_t)new_iface_decl, (uint64_t)isa);
- static ConstString NSObject_name("NSObject");
-
- if (name != NSObject_name)
- new_iface_decl->setHasExternalVisibleStorage();
+ new_iface_decl->setHasExternalVisibleStorage();
ast_ctx->getTranslationUnitDecl()->addDecl(new_iface_decl);
@@ -319,7 +316,7 @@
}
}
- clang::ObjCMethodDecl *BuildMethod (clang::ObjCInterfaceDecl *interface_decl, const char *name)
+ clang::ObjCMethodDecl *BuildMethod (clang::ObjCInterfaceDecl *interface_decl, const char *name, bool instance)
{
lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
@@ -330,7 +327,7 @@
clang::QualType return_qual_type;
- const bool isInstance = true;
+ const bool isInstance = instance;
const bool isVariadic = false;
const bool isSynthesized = false;
const bool isImplicitlyDeclared = true;
@@ -516,17 +513,27 @@
interface_decl->setSuperClass(superclass_decl);
};
- auto method_func = [log, interface_decl, this](const char *name, const char *types)
+ auto instance_method_func = [log, interface_decl, this](const char *name, const char *types)
{
ObjCRuntimeMethodType method_type(types);
- clang::ObjCMethodDecl *method_decl = method_type.BuildMethod (interface_decl, name);
+ clang::ObjCMethodDecl *method_decl = method_type.BuildMethod (interface_decl, name, true);
+
+ if (method_decl)
+ interface_decl->addDecl(method_decl);
+ };
+
+ auto class_method_func = [log, interface_decl, this](const char *name, const char *types)
+ {
+ ObjCRuntimeMethodType method_type(types);
+
+ clang::ObjCMethodDecl *method_decl = method_type.BuildMethod (interface_decl, name, false);
if (method_decl)
interface_decl->addDecl(method_decl);
};
- if (!descriptor->Describe(superclass_func, method_func))
+ if (!descriptor->Describe(superclass_func, instance_method_func, class_method_func))
return false;
if (log)
More information about the lldb-commits
mailing list